Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
是否回避了这两个java.io.File线程安全问题?_Java_Multithreading_File_Filesystems_Thread Safety - Fatal编程技术网

是否回避了这两个java.io.File线程安全问题?

是否回避了这两个java.io.File线程安全问题?,java,multithreading,file,filesystems,thread-safety,Java,Multithreading,File,Filesystems,Thread Safety,假设一个Win32FileSystem和beginmulti-threading在一个共享的多线程类对象上同时运行多次,那么最可能导致数据争用或其他线程问题的方式是什么?我知道这可能不是线程安全的,因为(1)setPath的参数被重用。我还看到(2)path不是java.io.File中的最终变量。然而,我似乎找不到由于线程问题,代码本身会出错的部分 public class MultiThreadingClass { private Holder h = new Holder();

假设一个
Win32FileSystem
beginmulti-threading
在一个共享的多线程类对象上同时运行多次,那么最可能导致数据争用或其他线程问题的方式是什么?我知道这可能不是线程安全的,因为(1)
setPath
的参数被重用。我还看到(2)
path
不是
java.io.File
中的最终变量。然而,我似乎找不到由于线程问题,代码本身会出错的部分

public class MultiThreadingClass {
    private Holder h = new Holder();
    private String path ="c:\\somepath"; 
    public void beginMultiThreading(){
        h.setPath(new File(path));
        h.begin();
    }
}

public class Holder {
    private File path;
    public void setPath(File path){
        this.path = path;
    }
    public void begin(){
        System.out.println(path.getCanonicalPath()+"some string");
    }
}

您的示例代码根本没有多线程。因此,我将假设多个线程要么在自己的
multi-threadingclass
实例上运行,要么在它们之间共享一个公共实例


无论如何,这段代码都是线程安全的。唯一的共享状态是私有字符串对象,它不作为方法的一部分进行调整

您的示例代码根本没有多线程。因此,我将假设多个线程要么在自己的
multi-threadingclass
实例上运行,要么在它们之间共享一个公共实例


无论如何,这段代码都是线程安全的。唯一的共享状态是私有字符串对象,它不作为方法的一部分进行调整

正如@Duncan所说,代码目前是线程安全的。但此时它不进行任何文件写入。当您使用文件对象时,我希望您将处理文件。一旦开始写入文件,还需要进一步考虑:

  • 从多个线程写入单个文件需要同步。据我所知,这不是“开箱即用”的功能
  • 从不同JVM甚至从同一JVM中的不同类装入器写入同一文件要困难得多。(对于大多数web框架,从多个web应用程序写入日志文件就是从不同类加载器写入单个文件的一个示例)。您又回到了使用锁文件或某种特定于平台的互斥

警告:我已经有一段时间没有这么做了,所以在最新的Java并发程序包或NIO程序包中可能会有更多的支持,其他人可以扩展。

正如@Duncan所说,代码目前是线程安全的。但此时它不进行任何文件写入。当您使用文件对象时,我希望您将处理文件。一旦开始写入文件,还需要进一步考虑:

  • 从多个线程写入单个文件需要同步。据我所知,这不是“开箱即用”的功能
  • 从不同JVM甚至从同一JVM中的不同类装入器写入同一文件要困难得多。(对于大多数web框架,从多个web应用程序写入日志文件就是从不同类加载器写入单个文件的一个示例)。您又回到了使用锁文件或某种特定于平台的互斥

警告:我已经有一段时间没有这样做了,因此,在最新的Java并发程序包或NIO程序包中可能会有更多的支持,其他人可以扩展。

不可变参数会被重用。因此,不,这很好,除非类文档在不同线程中处理多个实例是不安全的(比如它在内部以非线程安全的方式使用静态变量)@Voo谢谢你指出这个论点是不可变的。我将
setPath
参数更改为
File
。这仍然是线程安全的吗?一个不可变的参数会被重用。因此,不,这很好,除非类文档说明在不同线程中处理多个实例是不安全的(比如说它在内部以非线程安全的方式使用静态变量)。@Voo感谢您指出该参数是不可变的。我将
setPath
参数更改为
File
。这仍然是线程安全的吗?谢谢。他们正在共享一个共同的实例。我将
setPath
参数编辑为
File
,因为这就是我所看到的。这仍然是线程安全的吗?谢谢。他们正在共享一个共同的实例。我将
setPath
参数编辑为
File
,因为这就是我所看到的。这仍然是线程安全的吗?+1用于指出从多个线程写入文件的危险。FileChannel是一个具有线程安全性的Java NIO类。在FileChannel Javadoc中,“文件通道对于[来自同一JVM的]多个并发线程的使用是安全的”。+1用于指出从多个线程写入文件的危险。FileChannel是一个具有线程安全性的Java NIO类。在FileChannel Javadoc中,“多个并发线程[在同一JVM内]使用文件通道是安全的。”