Java多線程(八):ReentrantReadWriteLock

讀寫鎖ReentrantReadWriteLock概述

讀寫鎖ReentrantReadWriteLock,使用它比ReentrantLock效率更高。java

讀寫鎖表示兩個鎖,一個是讀操做相關的鎖,稱爲共享鎖;另外一個是寫操做相關的鎖,稱爲排他鎖。安全

一、讀和讀之間不互斥,由於讀操做不會有線程安全問題線程

二、寫和寫之間互斥,避免一個寫操做影響另一個寫操做,引起線程安全問題code

三、讀和寫之間互斥,避免讀操做的時候寫操做修改了內容,引起線程安全問題get

多個Thread能夠同時進行讀取操做,可是同一時刻只容許一個Thread進行寫入操做。it

讀操做和讀操做共享

請看例子
ThreadDomain44類和main方法io

public class ThreadDomain44 extends ReentrantReadWriteLock
{
    public void read()
    {
        try
        {
            readLock().lock();
            System.out.println(Thread.currentThread().getName() + "得到了讀鎖, 時間爲" +
                    System.currentTimeMillis());
            Thread.sleep(10000);
        }
        catch (InterruptedException e)
        {
            e.printStackTrace();
        }
        finally
        {
            readLock().unlock();
        }
    }

    public static void main(String[] args)
    {
        final ThreadDomain44 td = new ThreadDomain44();
        Runnable readRunnable = new Runnable()
        {
            public void run()
            {
                td.read();
            }
        };
        Thread t0 = new Thread(readRunnable);
        Thread t1 = new Thread(readRunnable);
        t0.start();
        t1.start();
    }
}

輸出結果以下class

Thread-0得到了讀鎖, 時間爲1564018325618
Thread-1得到了讀鎖, 時間爲1564018325618

儘管加了Thread.sleep(10000);兩個線程幾乎同時執行lock()後面的方法。說明readLock().lock()容許多個線程執行而且能提升執行效率。效率

寫操做和寫操做互斥

請看例子方法

public class ThreadDomain45 extends ReentrantReadWriteLock {
    public void write()
    {
        try
        {
            writeLock().lock();
            System.out.println(Thread.currentThread().getName() + "得到了寫鎖, 時間爲" +
                    new Date());
            Thread.sleep(10000);
        }
        catch (InterruptedException e)
        {
            e.printStackTrace();
        }
        finally
        {
            writeLock().unlock();
        }
    }

    public static void main(String[] args)
    {
        final ThreadDomain45 td = new ThreadDomain45();
        Runnable readRunnable = new Runnable()
        {
            public void run()
            {
                td.write();
            }
        };
        Thread t0 = new Thread(readRunnable);
        Thread t1 = new Thread(readRunnable);
        t0.start();
        t1.start();
    }
}

輸出結果

Thread-1得到了寫鎖, 時間爲Tue Jul 30 11:26:21 CST 2019
Thread-0得到了寫鎖, 時間爲Tue Jul 30 11:26:31 CST 2019

能夠看到,後得到鎖的Thread-0等待了十秒,說明寫和寫互斥

讀操做和寫操做互斥/寫操做和讀操做互斥

例子以下

public class ThreadDomain46 extends ReentrantReadWriteLock {
    public void write()
    {
        try
        {
            writeLock().lock();
            System.out.println(Thread.currentThread().getName() + "得到了寫鎖, 時間爲" +
                    new Date());
            Thread.sleep(10000);
        }
        catch (InterruptedException e)
        {
            e.printStackTrace();
        }
        finally
        {
            writeLock().unlock();
        }
    }

    public void read()
    {
        try
        {
            readLock().lock();
            System.out.println(Thread.currentThread().getName() + "得到了讀鎖, 時間爲" +
                    new Date());
            Thread.sleep(10000);
        }
        catch (InterruptedException e)
        {
            e.printStackTrace();
        }
        finally
        {
            readLock().unlock();
        }
    }

    public static void main(String[] args)
    {
        final ThreadDomain46 td = new ThreadDomain46();
        Runnable readRunnable = new Runnable()
        {
            public void run()
            {
                td.read();
            }
        };
        Runnable writeRunnable = new Runnable()
        {
            public void run()
            {
                td.write();
            }
        };
        Thread t0 = new Thread(readRunnable);
        Thread t1 = new Thread(writeRunnable);
        t0.start();
        t1.start();
    }
}

輸出結果以下

Thread-0得到了讀鎖, 時間爲Tue Jul 30 11:49:15 CST 2019
Thread-1得到了寫鎖, 時間爲Tue Jul 30 11:49:26 CST 2019

能夠看到Thread-0得到讀鎖執行完10s後Thread-1纔得到了寫鎖,說明讀操做和寫操做互斥。
另外一種輸出結果以下

Thread-1得到了寫鎖, 時間爲Tue Jul 30 14:14:07 CST 2019
Thread-0得到了讀鎖, 時間爲Tue Jul 30 14:14:17 CST 2019

能夠看到Thread-1得到寫鎖執行完10s後Thread-0纔得到了讀鎖,說明寫操做和讀操做互斥。

相關文章
相關標籤/搜索