对java中File.mkdirs方法线程安全问题的一点探讨
来源:互联网 发布:sql获得第十个数据 编辑:程序博客网 时间:2024/06/03 20:33
mkdirs是java中用来一次创建多级目录的方法,在java.io.File类中。
我在编程中遇到这样一段代码:
if (!dest.exists()) {
dest.mkdirs();
}
if (!dest.isDirectory()) {
throw new IOException(dest.getName() + " must be a directory!");
}
该段代码所在的方法会被多个线程调用。在某些次的运行中,dest.mkdirs方法创建目录就会失败,从而造成下面的if语句里的抛异常代码被执行。
JDK 1.5 update 21中的java.io.File.mkdirs代码如下:
public boolean mkdirs() {
if (exists()) {
return false;
}
if (mkdir()) {
return true;
}
File canonFile = null;
try {
canonFile = getCanonicalFile();
} catch (IOException e) {
return false;
}
String parent = canonFile.getParent();
return (parent != null) &&
(new File(parent, fs.prefixLength(parent)).mkdirs() &&
canonFile.mkdir());
}
考察该mkdirs源码,发现在这种可能的情形中,会出问题:两个线程都调用最前面那段代码,第一个线程中要创建的目录为“dirParent/dirA”,第二个线程要创建的目录为“dirParent/dirB”(执行以前dirParent目录不存在)。这两个线程都进入mkdirs方法,两个线程都没能直接创建目录并执行到“return”语句那一行,接下来,第一个线程执行完毕并成功创建了“dirParent/dirA”目录,这时第二个线程向前推进,对mkdirs方法的递归调用由于“dirParent”目录已存在而返回false,由“&&”运算符的短路机制,“canonFile.mkdir()”语句将不会被执行,也就是说“dirB”目录并没有被创建出来,且此时mkdirs也将返回false。于是,在第二个线程中,后面的抛出异常的语句就被执行。
这样看来,mkdirs方法并不是线程安全的。针对这段程序的实际情况,我将最上面的代码改成下面这样(FileUtils是该段代码所在的类,且该段代码所在的方法为静态方法):
if (!dest.exists()) {
synchronized (FileUtils.class) {
dest.mkdirs();
}
}
if (!dest.isDirectory()) {
throw new IOException(dest.getName() + " must be a directory!");
}
这样,问题就解决了。
- 对java中File.mkdirs方法线程安全问题的一点探讨
- 对java中File.mkdirs方法线程安全问题的一点探讨
- java.util.File 中,mkdir()方法和mkdirs()方法的区别
- java File类mkdir()与mkdirs()方法的区别:
- Java中File类mkdir和mkdirs的区别
- java.io.file 中mkdir和mkdirs的区别
- Java中线程的安全问题
- Java.io.File.mkdirs()方法实例
- JAVA 中File mkdir()与mkdirs()
- File中mkdir()和mkdirs()的区别
- 对 File.Delete 方法的一点看法
- 对 File.Delete 方法的一点看法
- 对 File.Delete 方法的一点看法
- 对 File.Delete 方法的一点看法
- java 类File的方法: mkdir()方法与mkdirs()的区别
- java 类File的方法: mkdir()方法与mkdirs()的区别
- 【Java】利用自带的file.mkdirs();创建文件夹与file.mkdirs();的注意事项
- java 中的renameTO/java.io.File中mkdir和mkdirs的区别
- asp.net操作文件,文件夹
- Windows消息的封装之:对话框与控件(二)
- 准备放假
- 小型简单的计算器
- 在Ubuntu 8.10下安装QQ for Linux的过程
- 对java中File.mkdirs方法线程安全问题的一点探讨
- 忠告与不要
- CVS在Ubuntu 9.04(Januty)中的bug(严重!)
- 事务对数据块的操作过程的分析和试验
- Java入门之JDK下载
- 常用DOS命令
- 派生类到基类的转换(c++学习笔记)
- 串口通信的基本概念
- 制作股票软件(1)