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 当一个线程正在访问一个方法时,如何防止其他线程访问该方法?_Java_Multithreading - Fatal编程技术网

Java 当一个线程正在访问一个方法时,如何防止其他线程访问该方法?

Java 当一个线程正在访问一个方法时,如何防止其他线程访问该方法?,java,multithreading,Java,Multithreading,我想在10个文件中搜索字符串,并将匹配的行写入单个文件。我将每个文件中的匹配行写入10个输出文件(o/p文件1、o/p文件2…),然后使用10个线程将它们复制到单个文件中 但是输出单个文件有混合输出(一行来自o/p文件1,另一行来自o/p文件2等等),因为它被多个线程同时访问。如果我等待所有线程完成,然后写入单个文件,速度会慢得多。 我希望输出文件一次由一个线程写入。我该怎么办 我的源代码:(仅写入单文件方法) public void WriteSingle(文件输出、文件最终输出)引发IOEx

我想在10个文件中搜索字符串,并将匹配的行写入单个文件。我将每个文件中的匹配行写入10个输出文件(o/p文件1、o/p文件2…),然后使用10个线程将它们复制到单个文件中

但是输出单个文件有混合输出(一行来自o/p文件1,另一行来自o/p文件2等等),因为它被多个线程同时访问。如果我等待所有线程完成,然后写入单个文件,速度会慢得多。 我希望输出文件一次由一个线程写入。我该怎么办

我的源代码:(仅写入单文件方法)

public void WriteSingle(文件输出、文件最终输出)引发IOException{
已同步(输出文件){
System.out.println(“写入单个文件”);
FileOutputStream fo=新的FileOutputStream(最终输出,true);
FileChannel fi=fo.getChannel();
FileInputStream fs=新的FileInputStream(输出文件);
FileChannel fc=fs.getChannel();
int maxCount=(64*1024*1024)-(32*1024);
长尺寸=fc.size();
长位置=0;
while(位置<大小){
位置+=fc.transferTo(位置,最大计数,fi);
}
}
}
在存在该方法之前,请确保
flush()
/
close()
所有流

并且,正如Xavier在评论中所指出的,确保在同一实例上调用该方法。因为同步发生在每个实例上(在本例中)

在存在该方法之前,请确保
flush()
/
close()
所有流

并且,正如Xavier在评论中所指出的,确保在同一实例上调用该方法。因为同步发生在每个实例上(在本例中)

源代码:

public void WriteSingle(File output_file,File final_output)
      throws IOException
  {
     synchronized(output_file){
        try{ 
            wait();
        }
        catch (InterruptedException e) { 
            e.printStackTrace(); 
        } 

     System.out.println("Writing Single file");
 FileOutputStream fo = new FileOutputStream(final_output,true);
     FileChannel fi = fo.getChannel();
     FileInputStream fs = new FileInputStream(output_file);
     FileChannel fc = fs.getChannel();
     int maxCount = (64 * 1024 * 1024) - (32 * 1024);
     long size = fc.size();
     long position = 0;
     while (position < size) {
       position += fc.transferTo(position, maxCount, fi);
     }
   }
public void WriteSingle(文件输出、文件最终输出)
抛出IOException
{
已同步(输出文件){
试试{
等待();
}
捕获(中断异常e){
e、 printStackTrace();
} 
System.out.println(“写入单个文件”);
FileOutputStream fo=新的FileOutputStream(最终输出,true);
FileChannel fi=fo.getChannel();
FileInputStream fs=新的FileInputStream(输出文件);
FileChannel fc=fs.getChannel();
int maxCount=(64*1024*1024)-(32*1024);
长尺寸=fc.size();
长位置=0;
while(位置<大小){
位置+=fc.transferTo(位置,最大计数,fi);
}
}
源代码:

public void WriteSingle(File output_file,File final_output)
      throws IOException
  {
     synchronized(output_file){
        try{ 
            wait();
        }
        catch (InterruptedException e) { 
            e.printStackTrace(); 
        } 

     System.out.println("Writing Single file");
 FileOutputStream fo = new FileOutputStream(final_output,true);
     FileChannel fi = fo.getChannel();
     FileInputStream fs = new FileInputStream(output_file);
     FileChannel fc = fs.getChannel();
     int maxCount = (64 * 1024 * 1024) - (32 * 1024);
     long size = fc.size();
     long position = 0;
     while (position < size) {
       position += fc.transferTo(position, maxCount, fi);
     }
   }
public void WriteSingle(文件输出、文件最终输出)
抛出IOException
{
已同步(输出文件){
试试{
等待();
}
捕获(中断异常e){
e、 printStackTrace();
} 
System.out.println(“写入单个文件”);
FileOutputStream fo=新的FileOutputStream(最终输出,true);
FileChannel fi=fo.getChannel();
FileInputStream fs=新的FileInputStream(输出文件);
FileChannel fc=fs.getChannel();
int maxCount=(64*1024*1024)-(32*1024);
长尺寸=fc.size();
长位置=0;
while(位置<大小){
位置+=fc.transferTo(位置,最大计数,fi);
}
}

<>代码> < P>如何使用锁拥有文件编写器类(即在实例上获得锁定,执行任何必要的写入操作,然后释放锁;有点像数据库事务))考虑将文件写入器的实例传递给需要执行写入的对象/方法。(有利于更简单的单元测试/嘲弄).< /P> < P>如何拥有一个带锁的文件编写器类(即在实例上获得锁,执行任何必要的写入,然后释放锁;有点像数据库事务)?考虑将文件写入器的实例传递给需要执行写入的对象/方法。(还有更简单的单元测试/模拟的好处)。

如果我理解这一点,您想防止两个线程写入同一个文件吗

最简单的方法是锁定文件本身,而不是
文件
对象:

public void WriteSingle(File output_file, File final_output) throws IOException {
    System.out.println("Writing Single file");
    FileOutputStream fo = new FileOutputStream(final_output,true);
    FileChannel fi = fo.getChannel();
    FileInputStream fs = new FileInputStream(output_file);
    FileChannel fc = fs.getChannel();

    FileLock lock = fi.lock(); // Get lock here, blocks until file is closed

    fc.transferTo(0, fc.size(), fi);

    fc.close();
    fi.close();
    fo.close();
    fs.close();
}

如果我理解这一点,您想阻止两个线程写入同一个文件吗

最简单的方法是锁定文件本身,而不是
文件
对象:

public void WriteSingle(File output_file, File final_output) throws IOException {
    System.out.println("Writing Single file");
    FileOutputStream fo = new FileOutputStream(final_output,true);
    FileChannel fi = fo.getChannel();
    FileInputStream fs = new FileInputStream(output_file);
    FileChannel fc = fs.getChannel();

    FileLock lock = fi.lock(); // Get lock here, blocks until file is closed

    fc.transferTo(0, fc.size(), fi);

    fc.close();
    fi.close();
    fo.close();
    fs.close();
}
public synchronized void WriteSingle(文件输出、文件最终输出)引发IOException{
System.out.println(“写入单个文件”);
FileOutputStream fo=新的FileOutputStream(最终输出,true);
FileChannel fi=fo.getChannel();
FileInputStream fs=新的FileInputStream(输出文件);
FileChannel fc=fs.getChannel();
int maxCount=(64*1024*1024)-(32*1024);
长尺寸=fc.size();
长位置=0;
while(位置<大小){
位置+=fc.transferTo(位置,最大计数,fi);
}
}
如果这不起作用,那么您可能正在使用多个实例写入文件。在这种情况下,您可以尝试使用如下类锁:

public void WriteSingle(File output_file,File final_output) throws IOException {
    synchronized(getClass()) {
       System.out.println("Writing Single file");
       FileOutputStream fo = new FileOutputStream(final_output,true);
       FileChannel fi = fo.getChannel();
       FileInputStream fs = new FileInputStream(output_file);
       FileChannel fc = fs.getChannel();
       int maxCount = (64 * 1024 * 1024) - (32 * 1024);
       long size = fc.size();
       long position = 0;
       while (position < size) {
           position += fc.transferTo(position, maxCount, fi);
       }
    }
}
public void WriteSingle(文件输出、文件最终输出)引发IOException{
已同步(getClass()){
System.out.println(“写入单个文件”);
FileOutputStream fo=新的FileOutputStream(最终输出,true);
FileChannel fi=fo.getChannel();
FileInputStream fs=新的FileInputStream(输出文件);
FileChannel fc=fs.getChannel();
int maxCount=(64*1024*1024)-(32*1024);
长尺寸=fc.size();
长位置=0;
while(位置<大小){
位置+=fc.transferTo(位置,最大计数,fi);
}
}
}
这并不理想,但它应该给我们一个关于您的代码正在做什么的提示

如果这两种方法都不起作用,那么您的通用编程逻辑可能是错误的,并且问题可能没有太大的影响
public void WriteSingle(File output_file,File final_output) throws IOException {
    synchronized(getClass()) {
       System.out.println("Writing Single file");
       FileOutputStream fo = new FileOutputStream(final_output,true);
       FileChannel fi = fo.getChannel();
       FileInputStream fs = new FileInputStream(output_file);
       FileChannel fc = fs.getChannel();
       int maxCount = (64 * 1024 * 1024) - (32 * 1024);
       long size = fc.size();
       long position = 0;
       while (position < size) {
           position += fc.transferTo(position, maxCount, fi);
       }
    }
}