演示使用ReadWriteLock

时间:2019-01-27 09:54:39

标签: java multithreading locking reentrantlock

我试图理解ReadWriteLock的概念,并实现了以下简单示例。据我了解,只要一个线程有一个readlock,另一个线程就可以获取readlock。但是对于具有writelock的线程,在其他线程释放锁之前,其他任何线程都无法获取write/read lock。但是,从下面程序的输出中,我注意到,在WriterOdd释放锁之前(打印释放锁的输出),Reader线程进入并读取number字符串。是因为在释放writelock之后,reader线程才进入,然后打印了释放writelock的print语句?

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");

    }

}

输出:

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 :(得分:3)

写关于释放写锁的控制台消息的代码行是在释放锁之后。

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