предоставление доступа только к одному объекту для чтения и записи файла - PullRequest
0 голосов
/ 25 марта 2012

Я хотел бы знать, если несколько потоков пытаются получить доступ к одному 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);
    }
}

Ответы [ 2 ]

1 голос
/ 25 марта 2012

Вы можете использовать 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();
}

Или, для чего-то более простого, вы можете синхронизироваться с интернированным (интернирование гарантирует, что объект String является общим)String объект, представляющий полное имя пути File:

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

Подход ReadWriteLock будет иметь более высокую производительность, поскольку Thread s будет разрешено читать файл одновременнов то время как синхронизация вручную не позволяет этого.

1 голос
/ 25 марта 2012

Интересный способ сделать это состоит в том, чтобы интернировать строковое значение FQN файла, а затем синхронизировать его. Более «традиционный» способ - использовать объект FileChannel и блокировать его, а другие процессы просто ждут блокировки, чтобы по очереди.

Предупреждение: ни одно из этих решений не разрешит конфликт между JVM или конфликт между JVM и другими внешними программами.

...