在文件中同步写入和读取没有文件的连接对象变量

时间:2015-04-14 18:33:43

标签: java multithreading file concurrency file-locking

我正在尝试在Java中实现线程并发。它包括尝试最后一次写入文件。有两个线程:A - 创建一个文件并检查文件中是否有正确的行和B - 正在搜索文件并尝试用“好”重写文件线。 “获胜者”主题必须在文件中包含字符串。要做它的线程检查文件是否有他们的行,文件只有一行。线程只有文件路径。

public class A implements Runnable {
private File file;
private Thread t;

public A(String patch,String fileName)
{
    t = new Thread(this);
    CreateFile(patch, fileName);
    //t.setDaemon(true);
    t.start();
}

@Override
public void run() {
    BufferedReader reader;
    while (!Thread.currentThread().isInterrupted()) {
        try {
            reader = new BufferedReader(new InputStreamReader(new FileInputStream(file)));
            if (reader.readLine().charAt(0) == 'B') {
                System.out.println("A try took file: " + file.getName());
                write();
            } else {
                System.out.println("A took file: " + file.getName());
            }
        } catch (FileNotFoundException e)
        {
            System.out.println("File read A" + e.toString());
        }
        catch (IOException e)
        {
            System.out.println("File read A"+e.toString());
        }
    }
}


private void write() {
    try {
        PrintWriter printWriter = new PrintWriter(file);
        printWriter.println("A took file: " + file.getName());
        System.out.println("A took file: " + file.getName());
        printWriter.close();
    } catch (Exception e) {
        System.out.println("File write A");
    }
}

public File CreateFile(String patch,String fileName) {
    File file = new File(patch,fileName+".txt");
    try {
        PrintWriter printWriter = new PrintWriter(file);
        printWriter.println("A took file: " + file.getName());
        System.out.println("A took file: " + file.getName());
        printWriter.close();
    } catch (Exception e) {
        System.out.println("File create A");
    }
    return file;
}
}

public class B implements Runnable {
private File file;
private Thread t;

public B(String patch,String fileName)
{
    t = new Thread(this);
    //t.setDaemon(true);
    FindFile(patch, fileName);
    t.start();
}

@Override
public void run() {
    BufferedReader reader;
    while (!Thread.currentThread().isInterrupted()) {
        try {
            reader = new BufferedReader(new InputStreamReader(new FileInputStream(file)));
            if (reader.readLine().charAt(0) == 'A') {
                System.out.println("B try took file: " + file.getName());
                write();
            } else {
                System.out.println("B took file: " + file.getName());
            }
        } catch (FileNotFoundException e)
        {
            System.out.println("File read B" + e.toString());
        }
        catch (IOException e)
        {
            System.out.println("File read B"+e.toString());
        }
    }
}


private void write() {
    try {
        PrintWriter printWriter = new PrintWriter(file);
        printWriter.println("B took file: " + file.getName());
        System.out.println("B took file: " + file.getName());
        printWriter.close();
    } catch (Exception e) {
        System.out.println("File write B");
    }
}

public File FindFile(String patch,String fileName) {
    File file= null;
    File folder = new File(patch);
    File[] listOfFiles = folder.listFiles();
    BufferedReader reader;
    for (int i = 0; i < listOfFiles.length; i++) {
        file = listOfFiles[i];
        if (file.getName().equals(fileName + ".txt")) {
            break;
        }
    }
    return file;
}
}

我希望以某种方式同步访问线程中的文件。在我的代码中,当我使用java.lang.NullPointerException时,我有readLine(),所以我认为这是因为线程没有对文件的同步访问(在每个完成的操作文件必须有一行之后)。我不能使用synchronized方法或块,因为线程没有文件的联合变量。有没有办法在文件中进行同步写作和阅读?

1 个答案:

答案 0 :(得分:0)

您可以使用 ReentrantReadWriteLock 进行同步。解析相同的锁以同步A和B.这里我修改了B.你也可以为A做同样的事。

public static class B implements Runnable {
        private File file;
        private Thread t;
        private ReentrantReadWriteLock lock;

        public B(String patch,String fileName, ReentrantReadWriteLock lock)
        {
            t = new Thread(this);
            this.lock = lock;
            //t.setDaemon(true);
            FindFile(patch, fileName);
            t.start();
        }

        @Override
        public void run() {
            BufferedReader reader;
            while (!Thread.currentThread().isInterrupted()) {
                try {
                    lock.readLock().lock();
                    reader = new BufferedReader(new InputStreamReader(new FileInputStream(file)));
                    if (reader.readLine().charAt(0) == 'A') {
                        lock.readLock().unlock();
                        lock.writeLock().lock();
                        System.out.println("B try took file: " + file.getName());
                        write();
                        lock.writeLock().unlock();
                    } else {
                        System.out.println("B took file: " + file.getName());
                    }
                } catch (FileNotFoundException e)
                {
                    System.out.println("File read B" + e.toString());
                }
                catch (IOException e)
                {
                    System.out.println("File read B"+e.toString());
                }
            }
        }


        private void write() {
            try {
                PrintWriter printWriter = new PrintWriter(file);
                printWriter.println("B took file: " + file.getName());
                System.out.println("B took file: " + file.getName());
                printWriter.close();
            } catch (Exception e) {
                System.out.println("File write B");
            }
        }

        public File FindFile(String patch,String fileName) {
            File file= null;
            File folder = new File(patch);
            File[] listOfFiles = folder.listFiles();
            BufferedReader reader;
            for (int i = 0; i < listOfFiles.length; i++) {
                file = listOfFiles[i];
                if (file.getName().equals(fileName + ".txt")) {
                    break;
                }
            }
            return file;
        }
    }