【问题标题】:giving access to only one object to read a file and write it只允许访问一个对象来读取和写入文件
【发布时间】:2012-03-25 18:36:54
【问题描述】:

我想知道如果多个线程尝试访问单个txt文件,如何限制它? 如果线程 A 尝试访问文件直到它完成读写部分,其他线程必须等待。这是我尝试过的。

package singleton;

/**
 *
 * @author Admin
 */
import java.io.*;
class ReadFileUsingThread
{
    public synchronized void readFromFile(final String f, Thread thread) {

    Runnable readRun = new Runnable() {
      public void run() {
        FileInputStream in=null;
        FileOutputStream out=null;
        String text = null;
        try{
          Thread.sleep(5000);
          File inputFile = new File(f);
          in = new FileInputStream(inputFile);
          byte bt[] =  new byte[(int)inputFile.length()];
          in.read(bt);
          text = new String(bt);
          //String file_name = "E:/sumi.txt";
          //File file = new File(file_name);
         // FileWriter fstream = new FileWriter("E:/sumi.txt");
          out = new FileOutputStream("E:/sumi.txt");
          out.write(bt);
          System.out.println(text);


       } catch(Exception ex) {
       }  
      }
    };
    thread = new Thread(readRun);
    thread.start();
  }

    public static void main(String[] args) 
    {
        ReadFileUsingThread files=new ReadFileUsingThread();
        Thread thread1=new Thread();
        Thread thread2=new Thread();
        Thread thread3=new Thread();

        String f1="C:/Users/Admin/Documents/links.txt";//,f2="C:/employee.txt",f3="C:/hello.txt";
        thread1.start();
        files.readFromFile(f1,thread1);
        thread2.start();
        files.readFromFile(f1,thread2);
        thread3.start();
        files.readFromFile(f1,thread3);
    }
}

【问题讨论】:

  • 对这个问题并不重要,但您正在 main 中创建(并启动)线程,而您不做任何事情 - 您正在 readFromFile 中启动新线程并替换参考到作为参数传递的线程。似乎没有必要。

标签: java multithreading singleton synchronized


【解决方案1】:

一种有趣的方法是对文件 FQN 的字符串值进行实习,然后对其进行同步。更“传统”的方式是使用FileChannel 对象并锁定它,而其他进程只需等待锁定,轮流进行。

警告:这些解决方案都不能解决 JVM 之间的争用,或 JVM 与其他外部程序之间的争用。

【讨论】:

    【解决方案2】:

    您可以使用ReentrantReadWriteLock

    ReadWriteLock lock = new ReentrantReadWriteLock();
    
    ...
    
    lock.readLock().lock();
    try {
      //do reading stuff in here
    } finally {
       lock.readLock().unlock();
    }
    
    ...
    
    lock.writeLock().lock();
    try {
      //do writing stuff in here
    } finally {
      lock.writeLock().unlock();
    }
    

    或者,对于更简单的事情,您可以在表示 File 的完整路径名的实习生(实习确保String 对象是共享的)String 对象上同步:

    synchronized(file.getAbsolutePath().intern()) {
       //do operations on that file here
    }
    

    ReadWriteLock 方法将具有更好的性能,因为Threads 将被允许同时读取文件,而手动同步不允许这样做。

    【讨论】:

    • @sahana 如果您采用ReadWriteLock 方法,任何尝试访问该文件的Thread 都应该可以访问lock,而其他部分应该是您正在读取/写入的位置文件。如果您采用同步方法,它应该包含您所有的读/写操作。
    • 我在一定程度上理解了。还在尝试。谢谢杰弗里。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-08-10
    • 2020-12-26
    • 1970-01-01
    • 2015-08-07
    • 2010-12-05
    • 2017-07-28
    • 1970-01-01
    相关资源
    最近更新 更多