線程同步:java
因此Java提供了更高級的java.util.concurrent包:安全
java.util.locks.ReentrantLock用於替代synchronized加鎖 synchronized是Java語言層面提供的,不需考慮異常 ReentrantLock是普通的Java類,要用try...finally來保證鎖可以正確釋放 <img src="https://img2018.cnblogs.com/blog/1418970/201906/1418970-20190612191718983-438603878.png" width="500" /> 當咱們使用ReenTrantLock的時候,咱們首先要經過new ReentrantLock()新建一個Lock對象。而後咱們先試圖用lock()方法得到當前對象的鎖。若是咱們得到鎖成功,就進入try代碼,最後在finally中用unlock()來釋放這個鎖。 <font color="red">注意:lock()方法必須在try代碼以外完成。由於lock()可能會失敗,而unlock()必定要在finally中完成。</font>多線程
class Count{ final Lock lock = new ReetrantLock(); //得到ReentrantLock對象 public void inc(){ lock.lock(); //得到當前對象的鎖可能會失敗,因此要放在try...finally外面 try{ n = n + 1; }finally{ lock.unlock(); //釋放鎖 } }
ReentrantLock:this
class Counter{ final Lock lock = new ReentrantLock(); private void inc() throws InterruptedException{ if(lock.tryLock(1, TimeUnit.SECONDS)){ try{ n = n + 1; }finally { lock.unlock(); } } } }
<font color="blue">使用ReentrantLock比直接使用synchronized更安全,由於synchronized會致使線程要麼得到鎖,要的永遠等待下去。而使用ReentrantLock的時候,咱們經過tryLock()在失敗的時候不會致使死鎖。</font>spa
import java.util.concurrent.locks.ReentrantLock; import java.util.concurrent.locks.Lock; class Counter{ private Lock lock = new ReentrantLock(); private int value = 0; public void add(int m){ lock.lock(); try{ value += m; }finally { lock.unlock(); } } public void dec(int m){ lock.lock(); try{ value -= m; }finally { lock.unlock(); } } public int get(){ lock.lock(); try{ return this.value; }finally { lock.unlock(); } } } public class Main{ final static int LOOP = 100; public static void main(String[] args) throws Exception{ Counter counter = new Counter(); Thread t1 = new Thread(){ public void run(){ for(int i=0;i<LOOP;i++){ counter.add(1); } } }; Thread t2 = new Thread(){ public void run(){ for(int i=0;i<LOOP;i++){ counter.dec(1); } } }; t1.start(); t2.start(); t1.join(); t2.join(); System.out.println(counter.get()); } }