今天講另外一個併發工具,叫讀寫鎖。讀寫鎖是一種分離鎖,是鎖應用中的一種優化手段。
考慮讀多寫少的狀況,這時若是咱們用synchronized或ReentrantLock直接修飾讀/寫方法何嘗不可,如:併發
public static class Rw { private int val; public synchronized int read() throws InterruptedException { Thread.sleep(1000); return val; } public synchronized void write(int value) throws InterruptedException { Thread.sleep(1000); this.val = value; } }
簡單有效。
若是咱們想作點優化的話(前面說了讀的狀況比較多),也許要用到讀寫鎖ReadWriteLock
了`。
先看代碼:工具
public static class Rw { private int val; public int read(Lock lock) throws InterruptedException { try { lock.lock(); Thread.sleep(1000); return val; } finally { lock.unlock(); } } public void write(Lock lock, int value) throws InterruptedException { try { lock.lock(); Thread.sleep(1000); this.val = value; } finally { lock.unlock(); } } }
調用:優化
private static ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock(); public static void main(String[] args) { final Rw rw = new Rw(); for (int i = 18; i < 20; i++) { new Thread(() -> { try { rw.write(readWriteLock.writeLock(),1); } catch (InterruptedException e) { e.printStackTrace(); } }).start(); } for (int i = 0; i < 18; i++) { new Thread(() -> { try { int read = rw.read(readWriteLock.readLock()); System.out.println(read); } catch (InterruptedException e) { e.printStackTrace(); } }).start(); } }
ReentrantReadWriteLock
是ReadWriteLock
的經常使用子類。
代碼邏輯比較簡單,讀的時候上讀鎖,寫的時候上寫鎖。只有寫的時候會阻塞等待,因此代碼大概2秒鐘執行結束。
這裏面只須要注意一個問題:全部和寫相關的都會阻塞,好比讀-寫同時進行,也會阻塞。this