ReentrantLock保證了只有一個線程能夠執行臨界區代碼。 <font color="green">臨界區代碼:任什麼時候候只有1個線程能夠執行的代碼塊。 臨界區指的是一個訪問共用資源(例如:共用設備或是共用存儲器)的程序片斷,而這些共用資源又沒法同時被多個線程訪問的特性。當有線程進入臨界區段時,其餘線程或是進程必須等待,有一些同步的機制必須在臨界區段的進入點與離開點實現,以確保這些共用資源是被互斥得到使用,例如:semaphore。只能被單一線程訪問的設備,例如:打印機。</font>java
public void inc(){ lock.lock(); try{ value += 1; }finally{ lock.unlock(); } } public int get(){ lock.lock(); try(){ return value; }finally{ lock.unlock(); } }
但有時候,這種保護有些過頭:瀏覽器
咱們指望:容許多個線程同時讀,但只要有一個線程在寫,其餘線程就必須等待。性能
使用ReadWriteLock能夠解決:this
class Counter{ final ReadWriteLock lock = new ReentrantReadWriteLock(); //分別得到readLock和writeLock final Lock rlock = lock.readLock(); final Lock wlock = lock.writeLock(); private int value = 0; public void inc(){ wlock.lock(); try{ value += 1; }finally { wlock.unlock(); } } public int get(){ rlock.lock(); try{ return this.value; }finally { rlock.unlock(); } } }
import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock; class Count{ private ReadWriteLock lock = new ReentrantReadWriteLock(); private Lock rlock = lock.readLock(); private Lock wlock = lock.writeLock(); private int value = 0; public void add(int m){ wlock.lock(); try{ value += m; }finally { wlock.unlock(); } } public void dec(int m){ wlock.lock(); try{ value -= m; }finally { wlock.unlock(); } } public int get(){ rlock.lock(); try{ return value; }finally { rlock.unlock(); } } } public class Main{ final static int LOOP = 100; public static void main(String[] args) throws Exception{ Count count = new Count(); Thread t1 = new Thread(){ public void run(){ for(int i=0;i<LOOP;i++){ count.add(1); } } }; Thread t2 = new Thread(){ public void run(){ for(int i=0;i<LOOP;i++){ count.dec(1); } } }; t1.start(); t2.start(); t1.join(); t2.join(); System.out.println(count.get()); } }
<img src="https://img2018.cnblogs.com/blog/1418970/201906/1418970-20190612202639771-792089703.png" width="500" />spa
ReadWriteLock適用條件:線程
使用ReadWriteLock能夠提升讀取效率:code