Пример, демонстрирующий использование ReadWriteLock - PullRequest
0 голосов
/ 27 января 2019

Я пытаюсь понять концепцию ReadWriteLock и реализовал приведенный ниже простой пример.Из того, что я понял, всякий раз, когда у потока есть readlock, другой поток может получить readlock.Но для потока с writelock никакой другой поток не может получить write/read lock, пока другой поток не снимет блокировку.Однако из вывода программы, представленной ниже, я заметил, что перед тем, как WriterOdd снимет блокировку (выводит выходные данные снятия блокировки), потоки Reader входят и читают строку number.Это потому, что сразу после освобождения потоков writelock появляются потоки reader, а затем печатается оператор print освобождения writelock?

public static void main(String[] args) {

    new Thread(new Reader(), "Reader 1").start();
    new Thread(new Reader(), "Reader 2").start();
    new Thread(new WriterEven(), "Writer Even").start();
    new Thread(new WriterOdd(), "Writer Odd").start();

}

public static class Reader implements Runnable {

    public void run() {

        for (int i = 1; i <= 6; i++) {
            rwl.readLock().lock();
            // rl.lock();
            System.out.println(Thread.currentThread().getName() + "  is reading" + number);
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } finally {
                rwl.readLock().unlock();
            }
        }

    }

}

public static class WriterEven implements Runnable {

    public void run() {
        System.out.println(Thread.currentThread().getName() + " is trying  writing");
        rwl.writeLock().lock();
        System.out.println(Thread.currentThread().getName() + " got the lock");
        for (int i = 2; i <= 6; i += 2) {

            System.out.println(Thread.currentThread().getName() + " is writing");
            number = number.concat(" " + i);
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } finally {

            }

        }
        rwl.writeLock().unlock();

        System.out.println(Thread.currentThread().getName() + " left the lock");

    }

}

public static class WriterOdd implements Runnable {

    public void run() {
        System.out.println(Thread.currentThread().getName() + " is trying  writing");
        rwl.writeLock().lock();
        System.out.println(Thread.currentThread().getName() + " got the lock");
        for (int i = 1; i <= 5; i += 2) {

            System.out.println(Thread.currentThread().getName() + " is writing");
            number = number.concat(" " + i);
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } finally {

            }

        }
        rwl.writeLock().unlock();
        System.out.println(Thread.currentThread().getName() + " left the lock");

    }

}

OUTPUT:

Reader 2  is reading0
Reader 1  is reading0
Writer Even is trying  writing
Writer Odd is trying  writing
Writer Even got the lock
Writer Even is writing
Writer Even is writing
Writer Even is writing
Writer Odd got the lock
Writer Odd is writing
Writer Even left the lock
Writer Odd is writing
Writer Odd is writing
Reader 1  is reading0 2 4 6 1 3 5
Reader 2  is reading0 2 4 6 1 3 5
Writer Odd left the lock

1 Ответ

0 голосов
/ 27 января 2019

Строка кода, которая записывает консольное сообщение о снятии блокировки записи, ПОСЛЕ снятия блокировки.

rwl.writeLock().unlock();
// here readers can read already
// because they are free to aquire lock
System.out.println(Thread.currentThread().getName() + " left the lock");
...