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