FileUtils类的方法,写文件时是否线程安全?比如:
FileUtils.writeStringToFile(new File("/home/test1/d.txt"), "1\n", "utf-8",true);
我追踪代码,发现该方法调用FileOutputStream的native方法:
private native void writeBytes(byte b[], int off, int len, boolean append)
throws IOException;
没见到锁。下面的1000个并发写文件,也没出现数据不一致
public static void multiple() throws InterruptedException {
ExecutorService pool = Executors.newFixedThreadPool(100);
ArrayList<Callable<Integer>> arrayList = new ArrayList<Callable<Integer>>();
for (int i = 0; i < 1000; i++) {
arrayList.add(()->{
FileUtils.writeStringToFile(new File("/home/test1/d.txt"), "1\n", "utf-8",true);
return 1;
});
}
pool.invokeAll(arrayList);
pool.shutdown();
}
这两种方法,你都能观察到不安全,使用 FileUtils 写入速度非常慢。
你这种方法能够观察到安全,是因为文件系统每次写入的数据,是有顺序的,如果你两次同时写入一千个字节,这两次的内容是不会截断的(我没有验证过如果两次写入的数据量非常巨大会怎么样),你写入的数据又短又是一致的。
安不安全取决于你怎么去使用,如果你要求我给出的代码中循环写入数据不被截断,那么就必须要使用加锁或者单个线程写入的方法。如果你要求写入速度快,那么就不能使用 FileUtils 频繁关闭打开文件流。
如果你两种需求都没有,速度上没要求,每次写入数据都是整块写入单个线程只写入一次,那么就是线程安全的。