一、效果和synchronized同樣,均可以同步執行,lock方法得到鎖,unlock方法釋放鎖java
使用示例:ide
package com.test; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; public class MyService { private Lock lock = new ReentrantLock(); public void methodA() { try { lock.lock(); System.out.println("methodA begin ThreadName = " + Thread.currentThread().getName() + "time=" + System.currentTimeMillis()); Thread.sleep(3000); System.out.println("methodA end ThreadName = " + Thread.currentThread().getName() + "time=" + System.currentTimeMillis()); } catch (Exception e) { e.printStackTrace(); } finally { lock.unlock(); } } public void methodB() { try { lock.lock(); System.out.println("methodB begin ThreadName = " + Thread.currentThread().getName() + "time=" + System.currentTimeMillis()); Thread.sleep(3000); System.out.println("methodB end ThreadName = " + Thread.currentThread().getName() + "time=" + System.currentTimeMillis()); } catch (Exception e) { e.printStackTrace(); } finally { lock.unlock(); } } }
package com.test; public class Run { public static void main(String[] args) { MyService myService = new MyService(); Thread t1 = new Thread(new Runnable() { @Override public void run() { myService.methodA(); } }); Thread t2 = new Thread(new Runnable() { @Override public void run() { myService.methodB(); } }); t1.start(); t2.start(); } }
結果: methodA begin ThreadName = Thread-0time=1527821296840 methodA end ThreadName = Thread-0time=1527821299841 methodB begin ThreadName = Thread-1time=1527821299841 methodB end ThreadName = Thread-1time=1527821302841
注意:必需要在finally塊裏調用lock.unlock() 釋放鎖.spa
二、使用Condition實現等待/通知:線程
awati() 與 signal() 方法:code
package com.test; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; public class MyService { private Lock lock = new ReentrantLock(); private Condition condition = lock.newCondition(); public void testWait() { try { lock.lock(); System.out.println("wait"); condition.await(); } catch (Exception e) { e.printStackTrace(); } finally { lock.unlock(); } } public void testSignal() { try { lock.lock(); condition.signal(); } finally { lock.unlock(); } } }
三、公平鎖和非公平鎖:對象
公平鎖標識線程獲取鎖的順序是按照線程加鎖的順序來分配的。即先來先得的FIFO先進先出順序。而非公平鎖就是一種獲取鎖的搶佔機制,是隨機得到鎖的。blog
Lock lock=new ReentrantLock(true);//公平鎖 Lock lock=new ReentrantLock(false);//非公平鎖
四、ReentrantLock 類的方法:get
五、ReentrantReadWriteLock 類,讀寫鎖:同步
類ReentrantLock 具備徹底互斥排他的效果,即同一時間只有一個線程在執行lock()方法後面的任務。it
讀寫鎖表示也有兩個鎖,一個是讀操做相關的鎖,也成爲共享鎖;另外一個是寫操做相關的鎖,也就排它鎖。也就是多個讀鎖之間不互斥,讀鎖與寫鎖互斥,寫鎖與寫鎖互斥。在沒有線程進行寫操做時,進行讀取操做的多個線程均可以獲取讀鎖,而進行寫入操做的線程只有在獲取寫鎖後才能進行寫入操做。即多個線程能夠同時進行讀操做,但同一時刻只有一個線程能夠進行寫操做。
private ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); public void read() { try { try { lock.readLock().lock(); System.out.println("獲取讀鎖:" + System.currentTimeMillis()); Thread.sleep(1000); } finally { lock.readLock().unlock(); } } catch (Exception e) { e.printStackTrace(); } }
private ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); public void write() { try { try { lock.writeLock().lock(); System.out.println("獲取寫鎖:" + System.currentTimeMillis()); Thread.sleep(1000); } finally { lock.writeLock().unlock(); } } catch (Exception e) { e.printStackTrace(); } }
private ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); public void read() { try { try { lock.writeLock().lock(); System.out.println("獲取讀鎖:" + System.currentTimeMillis()); Thread.sleep(1000); } finally { lock.writeLock().unlock(); } } catch (Exception e) { e.printStackTrace(); } } public void write() { try { try { lock.writeLock().lock(); System.out.println("獲取寫鎖:" + System.currentTimeMillis()); Thread.sleep(1000); } finally { lock.writeLock().unlock(); } } catch (Exception e) { e.printStackTrace(); } }
lock 與 lockInterruptibly比較區別在於:
lock 優先考慮獲取鎖,待獲取鎖成功後,才響應中斷。
lockInterruptibly 優先考慮響應中斷,而不是響應鎖的普通獲取或重入獲取
synchronized 和 lock 的用法區別:
使用ReentrantLock的場景: