1

I have been given this problem in which if a file is currently getting read, no write operation can occur on it and vice versa, using wait() and notify(). I have tried to come up with a solution but after first read the program only does the write operation and gets stuck. Here's the code

public static boolean LOCK = false;

public synchronized void read() {
    String path = "/path/to/file/working.txt";

    while (LOCK == true) {
        try {
            System.out.println("reading paused..");
            wait();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    try (BufferedReader bin = new BufferedReader(new FileReader(path))) {
        LOCK = true;
        String line = "";
        System.out.println("reading now..");
        while ((line = bin.readLine()) != null) {
            System.out.println(line);
        }

        LOCK = false;
        notify();

    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }

}

public synchronized void write(String word) {

    String path = "/path/to/file/working.txt";

    while (LOCK == true) {
        try {
            System.out.println("writing paused..");
            wait();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    try (PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(path, true)))) {
        System.out.println("writing resumed..");
        LOCK = true;
        out.println(word);
        LOCK = false;
        notify();

    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

I passed an String array of fruits as test, lauching read() and write() as seperate threads and the output I'm getting is,

Writing resumed..
reading..
Apple
Writing resumed..
Writing resumed..
Writing resumed..

The output gets written completly but no read operation occurs after the first word. Please can you tell me what I'm doing wrong? Thank you.

Here's the test code,

String[] fruits = { "Apple", "Banana", "Orange", "Cherry", "Date", "ElderBerry", "Marionberry", "Blueberry", };

        FileSyncDemo fileDemo = new FileSyncDemo();

        Runnable r = () -> {

        try {
                fileDemo.read();
                Thread.sleep((long) (Math.random() * 1000));
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

        };

        Runnable r2 = () -> {

            try {
                for (int i = 0; i < fruits.length; i++) {
                    fileDemo.write(fruits[i]);
                    Thread.sleep((long) (Math.random() * 1000));
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

        };

        Thread t = new Thread(r);
        t.start();

        Thread t2 = new Thread(r2);
        t2.start();

    }
Alcazar
  • 11
  • 3
  • 1
    Unfortunately everything is wrong, that's not how locks work. You might want to start [here](https://docs.oracle.com/javase/tutorial/essential/concurrency/) – m0skit0 Feb 01 '19 at 17:10
  • This is an interesting question, I don't think it should be closed ! At least he let you understand the question correctly, and is trying to figure out a solution. – Eric Feb 01 '19 at 17:15
  • Basically, my idea is each file needs a counter, when it's 0, either reader or writer could acquire the lock, and each reader increase it by 1, each writer decrease it by 1, they will change it back when finish; when > 0, only reader could carry on, when < 0, only writer could carry on. – Eric Feb 01 '19 at 17:21
  • 2
    Given that you have synchronized the read and write methods, there is no need for the locks or any other thread safety mechanisms. The methods will never be able to interleave at all anyway. – Michael Feb 01 '19 at 17:24
  • misread the problem, duplicate wasn't valid, reopened. having your LOCK variable be in static scope while acquiring the lock on the object instance is error-prone. – Nathan Hughes Feb 01 '19 at 18:06
  • please also post the invocation of your read and write methods... – xerx593 Feb 01 '19 at 18:21
  • Without having looked toooo closely, only a pointer that may be relevant: https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/locks/ReadWriteLock.html – Marco13 Feb 01 '19 at 19:26
  • Michael , so should I not use synchronize keyword there? I'm supposed to solve the problem using wait() and notify(). I read that 'synchronized' and wait()-notify() are not mutually exclusive. – Alcazar Feb 02 '19 at 05:40
  • I used the variable lock because as far as I know the wait condition is suppposed to be put inside a condition using a while loop, so it does not get stuck there waiting forever. I could not think of any other way except using a single lock variable that would let the other method know it's acquring that file. – Alcazar Feb 02 '19 at 05:47

0 Answers0