ReentrantLock也可以讓代碼塊原子執行,可是比synchronized更增強大,ReentrantLock具備嗅探鎖定、多路分支通知等功能。
嗅探鎖定:是指獲取鎖時若是鎖已經被其餘線程獲取到ReentrantLock能夠進行指定等待時間獲取鎖或者
多路分支通知:是指線程發生await時,線程能夠選擇註冊在不一樣的監視器Condition對象上,在適當的時候能夠選擇指定的監視器Condition對象上的線程進行signal通知、執行java
import java.util.concurrent.locks.ReentrantLock; class MyService { private ReentrantLock lock = new ReentrantLock(); public void method() { try { lock.lock(); for (int i = 1; i <= 3; i++) { Thread.sleep(1000); System.out.println("ThreadName=" + Thread.currentThread().getName() + " " + i); } } catch (InterruptedException e) { e.printStackTrace(); }finally { lock.unlock(); } } } class MyThread extends Thread { private MyService service; MyThread(MyService service) { this.service = service; } @Override public void run() { service.method(); } } public class Test { public static void main(String[] args) { MyService service = new MyService(); MyThread myThread1 = new MyThread(service); MyThread myThread2 = new MyThread(service); myThread1.start(); myThread2.start(); } }
結果
ThreadName=Thread-0 1
ThreadName=Thread-0 2
ThreadName=Thread-0 3
ThreadName=Thread-1 1
ThreadName=Thread-1 2
ThreadName=Thread-1 3多線程
import java.util.concurrent.locks.ReentrantLock; class MyService { private ReentrantLock lock = new ReentrantLock(); public void methodA() { lock.lock(); try { System.out.println("MethodA begin ThreadName=" + Thread.currentThread().getName()); for (int i = 1; i <= 3; i++) { System.out.println("ThreadName=" + Thread.currentThread().getName() + " " + i); Thread.sleep(1000); } System.out.println("MethodA end ThreadName=" + Thread.currentThread().getName()); } catch (InterruptedException e) { e.printStackTrace(); } finally { lock.unlock(); } } public void methodB() { lock.lock(); try { System.out.println("MethodB begin ThreadName=" + Thread.currentThread().getName()); for (int i = 1; i <= 3; i++) { System.out.println("ThreadName=" + Thread.currentThread().getName() + " " + i); Thread.sleep(1000); } System.out.println("MethodB end ThreadName=" + Thread.currentThread().getName()); } catch (InterruptedException e) { e.printStackTrace(); } finally { lock.unlock(); } } } class ThreadA extends Thread { private MyService service; ThreadA(MyService service) { this.service = service; } @Override public void run() { service.methodA(); } } class ThreadB extends Thread { private MyService service; ThreadB(MyService service) { this.service = service; } @Override public void run() { service.methodB(); } } public class Test { public static void main(String[] args) { MyService service = new MyService(); ThreadA threadA = new ThreadA(service); threadA.setName("A"); ThreadB threadB = new ThreadB(service); threadB.setName("B"); threadA.start(); threadB.start(); } }
結果:
MethodA begin ThreadName=A
ThreadName=A 1
ThreadName=A 2
ThreadName=A 3
MethodA end ThreadName=A
MethodB begin ThreadName=B
ThreadName=B 1
ThreadName=B 2
ThreadName=B 3
MethodB end ThreadName=Bide
當多線程進入await狀態時,利用Condition監視器對不一樣類型線程通知測試
import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.ReentrantLock; class MyService { private ReentrantLock lock = new ReentrantLock(); private Condition conditionA = lock.newCondition(); private Condition conditionB = lock.newCondition(); public void methodA() { lock.lock(); try { System.out.println("MethodA begin ThreadName=" + Thread.currentThread().getName() + " " + System.currentTimeMillis()); conditionA.await(); System.out.println("MethodA end ThreadName=" + Thread.currentThread().getName() + " " + System.currentTimeMillis()); } catch (InterruptedException e) { e.printStackTrace(); } finally { lock.unlock(); } } public void methodB() { lock.lock(); try { System.out.println("MethodB begin ThreadName=" + Thread.currentThread().getName() + " " + System.currentTimeMillis()); conditionB.await(); System.out.println("MethodB end ThreadName=" + Thread.currentThread().getName() + " " + System.currentTimeMillis()); } catch (InterruptedException e) { e.printStackTrace(); } finally { lock.unlock(); } } public void signalA() { lock.lock(); conditionA.signal(); lock.unlock(); } public void signalA_All() { lock.lock(); conditionA.signalAll(); lock.unlock(); } public void signalB() { lock.lock(); conditionB.signal(); lock.unlock(); } public void signalB_All() { lock.lock(); conditionB.signalAll(); lock.unlock(); } } class ThreadA extends Thread { private MyService service; ThreadA(MyService service) { this.service = service; } @Override public void run() { service.methodA(); } } class ThreadB extends Thread { private MyService service; ThreadB(MyService service) { this.service = service; } @Override public void run() { service.methodB(); } } public class Test { public static void main(String[] args) throws InterruptedException { MyService service = new MyService(); ThreadA threadA = new ThreadA(service); threadA.setName("A"); ThreadB threadB = new ThreadB(service); threadB.setName("B"); threadA.start(); threadB.start(); Thread.sleep(1000); service.signalA(); Thread.sleep(1000); service.signalB(); // ThreadA[] threadAs = new ThreadA[10]; // for (int i=0;i<5;i++){ // threadAs[i] = new ThreadA(service); // } // ThreadB[] threadBs = new ThreadB[10]; // for (int i=0;i<5;i++){ // threadBs[i] = new ThreadB(service); // } // // for (int i=0;i<5;i++){ // threadAs[i].start(); // threadBs[i].start(); // } // // Thread.sleep(1000); // service.signalA_All(); // Thread.sleep(1000); // service.signalB_All(); } }
測試結果1:
MethodA begin ThreadName=A 1476800025028
MethodB begin ThreadName=B 1476800025029
MethodA end ThreadName=A 1476800026028
MethodB end ThreadName=B 1476800027028this
修改代碼爲:spa
public static void main(String[] args) throws InterruptedException { MyService service = new MyService(); // ThreadA threadA = new ThreadA(service); // threadA.setName("A"); // // ThreadB threadB = new ThreadB(service); // threadB.setName("B"); // threadA.start(); // threadB.start(); // // Thread.sleep(1000); // service.signalA(); // Thread.sleep(1000); // service.signalB(); ThreadA[] threadAs = new ThreadA[10]; for (int i=0;i<5;i++){ threadAs[i] = new ThreadA(service); } ThreadB[] threadBs = new ThreadB[10]; for (int i=0;i<5;i++){ threadBs[i] = new ThreadB(service); } for (int i=0;i<5;i++){ threadAs[i].start(); threadBs[i].start(); } Thread.sleep(1000); service.signalA_All(); Thread.sleep(1000); service.signalB_All(); }
結果爲:
MethodA begin ThreadName=Thread-0 1476800227416
MethodB begin ThreadName=Thread-7 1476800227417
MethodB begin ThreadName=Thread-5 1476800227417
MethodA begin ThreadName=Thread-3 1476800227418
MethodA begin ThreadName=Thread-1 1476800227418
MethodA begin ThreadName=Thread-4 1476800227418
MethodB begin ThreadName=Thread-6 1476800227418
MethodA begin ThreadName=Thread-2 1476800227418
MethodB begin ThreadName=Thread-8 1476800227418
MethodB begin ThreadName=Thread-9 1476800227418
MethodA end ThreadName=Thread-0 1476800228419
MethodA end ThreadName=Thread-3 1476800228419
MethodA end ThreadName=Thread-1 1476800228419
MethodA end ThreadName=Thread-4 1476800228420
MethodA end ThreadName=Thread-2 1476800228420
MethodB end ThreadName=Thread-7 1476800229419
MethodB end ThreadName=Thread-5 1476800229419
MethodB end ThreadName=Thread-6 1476800229419
MethodB end ThreadName=Thread-8 1476800229419
MethodB end ThreadName=Thread-9 1476800229419.net
四、公平所與非公平鎖
公平鎖是指線程獲(getting)取鎖的順序和線程鎖定(got)的順序相同,線程
Lock的一些方法說明
A) getHoldCount()
獲取當前鎖定(got)的個數
B)getQueueLength()
獲取當前正在等待獲取(getting)鎖的線程數(Threads)
C)getWaitQueueLength(Condition)
返回等待(await)與此鎖定(got)的Condition相關的個數code
版權聲明:本文爲博主原創文章,未經博主容許不得轉載。 http://blog.csdn.net/jihaitaowangyi/article/details/52852693對象