【发布时间】:2014-09-14 07:06:33
【问题描述】:
如果多个线程并行调用apachecommons ioFileUtils.contentEquals()静态方法会发生什么?
由于这个方法只包含局部变量,我们可以保证每次执行的最终结果没有任何竞争条件吗?
请就此提出建议。
【问题讨论】:
标签: java multithreading
如果多个线程并行调用apachecommons ioFileUtils.contentEquals()静态方法会发生什么?
由于这个方法只包含局部变量,我们可以保证每次执行的最终结果没有任何竞争条件吗?
请就此提出建议。
【问题讨论】:
标签: java multithreading
这取决于您的多个线程传递相同的参数还是不同的参数。具有不同参数的多个线程应该是线程安全的,因为没有资源争用。
如果您通过多个线程传递相同的参数,我首先会质疑是否需要这样做。但是忽略这一点,应该没问题,因为该方法创建了独立的输入流。在这种情况下,唯一可能出错的是操作系统抱怨多次访问同一文件。
【讨论】:
此方法调用 IOUtils.contentEquals,我认为,在多线程环境中没有什么可以制造竞争条件。
FileUtils.contentEquals()
public static boolean contentEquals(File file1, File file2) throws IOException {
boolean file1Exists = file1.exists();
if (file1Exists != file2.exists()) {
return false;
}
if (!file1Exists) {
// two not existing files are equal
return true;
}
if (file1.isDirectory() || file2.isDirectory()) {
// don't want to compare directory contents
throw new IOException("Can't compare directories, only files");
}
if (file1.length() != file2.length()) {
// lengths differ, cannot be equal
return false;
}
if (file1.getCanonicalFile().equals(file2.getCanonicalFile())) {
// same file
return true;
}
InputStream input1 = null;
InputStream input2 = null;
try {
input1 = new FileInputStream(file1);
input2 = new FileInputStream(file2);
return IOUtils.contentEquals(input1, input2);
} finally {
IOUtils.closeQuietly(input1);
IOUtils.closeQuietly(input2);
}
}
IOUtils.contentEquals()
public static boolean contentEquals(InputStream input1, InputStream input2)
throws IOException {
if (!(input1 instanceof BufferedInputStream)) {
input1 = new BufferedInputStream(input1);
}
if (!(input2 instanceof BufferedInputStream)) {
input2 = new BufferedInputStream(input2);
}
int ch = input1.read();
while (EOF != ch) {
int ch2 = input2.read();
if (ch != ch2) {
return false;
}
ch = input1.read();
}
int ch2 = input2.read();
return ch2 == EOF;
}
【讨论】:
通过查看 FileUtils.contentEquals 的源代码,它使用 BufferedInputStream 来比较两个文件(通过将两个文件的 InputStream 提供给 IOUtils.contentEquals)。
而且由于 BufferedInputStream 应该是线程安全的(至少我读过它,我自己从未尝试过),我认为 FileUtils.contentEquals 也应该是线程安全的。
【讨论】: