日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問(wèn)題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷解決方案
去故就新Java線程新同步機(jī)制

1、可重入鎖ReentrantLock,相當(dāng)于synchronized塊,為臨界區(qū)提供互斥訪問(wèn)機(jī)制。

(1) 相關(guān)的接口

創(chuàng)建一個(gè)可重入鎖

 
 
 
  1. Lock lock = new ReentrantLock();

請(qǐng)求鎖,如果鎖被當(dāng)前另一個(gè)線程持有,則阻塞。

 
 
 
  1. void lock();

釋放鎖

 
 
 
  1. void unlock();

非阻塞型lock()

 
 
 
  1. boolean tryLock();


(2) 使用基本結(jié)構(gòu)

 
 
 
  1. locker.lock();
  2. try{
  3. //code here to access the cirtical section
  4. }finally{
  5. locker.unlock();
  6. }

這種結(jié)構(gòu)保證在任何時(shí)刻只有一個(gè)線程能夠進(jìn)入臨界區(qū),如果一個(gè)線程鎖住了鎖對(duì)象,其他任何線程在調(diào)用lock時(shí),都會(huì)被阻塞,直到第一個(gè)線程釋放鎖對(duì)象。而且無(wú)論try塊是否拋出異常,都會(huì)執(zhí)行finally block,解鎖locker。

(3) 鎖的可重入性

鎖是可重入的,線程能夠重復(fù)地獲取它已經(jīng)擁有的鎖。鎖對(duì)象維護(hù)一個(gè)持有計(jì)數(shù)(hold count)來(lái)追蹤對(duì)lock方法的嵌套調(diào)用。線程在每次調(diào)用lock后都要調(diào)用unlock來(lái)釋放鎖。由于這個(gè)特性,被一個(gè)鎖保護(hù)的代碼可以調(diào)用另一個(gè)使用相同鎖的方法。

(4) 示例代碼:

 
 
 
  1. import java.util.concurrent.locks.Lock;
  2. import java.util.concurrent.locks.ReentrantLock;
  3. class WorkerOne extends Thread{
  4.     private Lock locker;
  5.     public WorkerOne (Lock locker){
  6.         this.locker = locker;
  7.     }
  8.     
  9.     public void run(){
  10.         locker.lock();
  11.         try{
  12. System.out.println(Thread.currentThread().getName()+":step into critical section");
  13.         }finally{
  14.             locker.unlock();    
  15.         }
  16.     }
  17. }
  18. class WorkerTwo extends Thread{
  19.     private Lock locker;
  20.     public WorkerTwo (Lock locker){
  21.         this.locker = locker;
  22.     }
  23.     
  24.     public void sayHello(){
  25.         locker.lock();
  26.         try{    System.out.println(Thread.currentThread().getName()+":call sayHello()");
  27.             Thread.sleep(1000);
  28.         } catch (InterruptedException e) {
  29.             e.printStackTrace();
  30.         }finally{
  31.             locker.unlock();
  32.         }
  33.     }
  34.     
  35.     public void run(){
  36.         locker.lock();  
  37.         try{        System.out.println(Thread.currentThread().getName()+":setp into critical section");
  38.                         //測(cè)試鎖的可重入性 
  39.             sayHello();
  40.         }finally{
  41.             locker.unlock();    
  42.         }
  43.     }
  44. }
  45. public class Test5 {
  46.     public static void main(String[] args) {
  47.         Lock locker = new ReentrantLock();
  48.         WorkerOne wo= new WorkerOne(locker);
  49.         wo.setName("WorkerOne");
  50.         WorkerTwo wt = new WorkerTwo(locker);
  51.         wt.setName("WorkerTwo");
  52.         
  53.         wt.start();
  54.         wo.start(); 
  55.     }
  56. }

輸出:

WorkerTwo:setp into critical section
WorkerTwo:call sayHello()
WorkerOne:step into critical section

2、條件對(duì)象Condition,相當(dāng)于wait-notify機(jī)制,提供一種線程間的等待通知機(jī)制,condition中的等待-通知方法是await(),signal(),signalAll(),也需要在互斥環(huán)境下被調(diào)用。

(1) 相關(guān)的接口

創(chuàng)建Condition對(duì)象,Condition對(duì)象是跟Lock關(guān)聯(lián)在一起的。

 
 
 
  1. Lock locker = new ReentrantLock();
  2. Condition cond = locker.newCondition();

把此線程放到條件的等待集中。

 
 
 
  1. void await();

解除此條件的等待集中所有線程的阻塞狀態(tài)。

 
 
 
  1. void signalAll();

在此條件的等待集中隨機(jī)選擇一個(gè)線程,解除其阻塞狀態(tài)。

 
 
 
  1. void signal();

(2) 使用的基本結(jié)構(gòu):

 
 
 
  1. //初始時(shí)ok_to_proceed為false.
  2. locker.lock()
  3. try{
  4.      while(!ok_to_proceed){
  5. //進(jìn)入等待此條件集中,被阻塞,它維持狀態(tài)直到另一個(gè)線程調(diào)用同一個(gè)條件上的。
  6. //signalAll/signal方法時(shí)為止。
  7.        cond.await();
  8.      }
  9. }finally{
  10. cker.unlock();
  11. }
 
 
 
  1. locker.lock();
  2.    try{
  3.       //調(diào)用將解除所有等待此條件下的線程的阻塞狀態(tài)。當(dāng)線程從等待集中被移走時(shí),它們將再次成為可運(yùn)行的,調(diào)度器將再次激活它們    
  4.       //此時(shí),它們將試圖重新進(jìn)入對(duì)象。一旦鎖可獲得,它們中的某個(gè)線程將從await調(diào)用返回,從而獲得鎖并從它被阻塞的地方繼續(xù)執(zhí)行。
  5.       ok_to_proceed = true;
  6.       cond.signalAll() or cond.signal();
  7.    }finally{
  8.        locker.unlock();
  9.    }

ok_to_proceed也是為了防止wait-notify出現(xiàn)的問(wèn)題,即再wait之間,notify()已經(jīng)給出通知,此時(shí)wait只會(huì)一直等待下去,這樣就保證了signal()線程的通知被await()線程接收到。

(3) 測(cè)試代碼:

 
 
 
  1. import java.util.concurrent.locks.Condition;
  2. import java.util.concurrent.locks.Lock;
  3. import java.util.concurrent.locks.ReentrantLock;
  4. class GlobalV{
  5.     public final static Lock locker = new ReentrantLock();
  6.     public final static Condition cond = locker.newCondition();
  7.     public static boolean to_proceed = false;
  8. }
  9. class Response extends Thread{
  10.     public void run(){
  11.         while(true){
  12.             GlobalV.locker.lock();
  13.             try{
  14.                 while(!GlobalV.to_proceed){
  15.                     GlobalV.cond.await();
  16.                 }
  17. System.out.println("Response:finish a job");
  18.                 GlobalV.to_proceed = false;
  19.                 
  20.             }catch(Exception e){
  21.                 e.printStackTrace();
  22.             }finally{
  23.                 GlobalV.locker.unlock();
  24.             }   
  25.         }
  26.     }
  27. }
  28. class Request extends Thread{
  29.     public void run(){
  30.         while(true){
  31.             GlobalV.locker.lock();  
  32.             try{
  33.                 GlobalV.to_proceed = true;
  34.                 GlobalV.cond.signalAll();
  35.                 System.out.println("Request:send a job to Response");   
  36.             }finally{
  37.                 GlobalV.locker.unlock();
  38.             }
  39.             try {
  40.                 Thread.sleep(2000);
  41.             } catch (InterruptedException e) {
  42.                 e.printStackTrace();
  43.             }
  44.         }
  45.     }
  46. }
  47. public class Test6 {
  48.     public static void main(String[] args) {
  49.         Request req = new Request();
  50.         Response res = new Response();
  51.         req.start();
  52.         res.start();
  53.     }
  54. }

輸出:

Request:send a job to Response
Response:finish a job
Request:send a job to Response
Response:finish a job
Request:send a job to Response
Response:finish a job
Request:send a job to Response
Response:finish a job

#p#

3、讀寫(xiě)鎖ReentrantReadWriteLock,適用于"讀多寫(xiě)少"的多線程應(yīng)用場(chǎng)景,"讀-寫(xiě)"互斥,"寫(xiě)-寫(xiě)"互斥,而讀-讀可以共享同讀鎖,即一個(gè)線程獲取讀鎖,其它線程可直接進(jìn)入讀,不會(huì)被阻塞。

(1) 相關(guān)接口

創(chuàng)建讀寫(xiě)鎖對(duì)象

 
 
 
  1. ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock();

獲取讀鎖

 
 
 
  1. Lock readLock = rwLock.readLock();

獲取寫(xiě)鎖

 
 
 
  1. Lock writeLock = rwLock.writeLock();

(2).讀寫(xiě)鎖使用基本結(jié)構(gòu)

 
 
 
  1. //對(duì)所有的讀操作添加讀鎖
  2. readLock.lock();
  3. try{
  4. //code to read
  5. }finally{
  6. readLock.unlock();
 
 
 
  1. //對(duì)所有的寫(xiě)操作添加寫(xiě)鎖
  2.   writeLock.lock(); 
  3.    try{ 
  4. //code to write 
  5.    }finally{ 
  6.     writeLock.unlock(); 
  7.    } 

(3) 測(cè)試代碼:

 
 
 
  1. import java.util.concurrent.locks.Lock;
  2. import java.util.concurrent.locks.ReentrantReadWriteLock;
  3. class Reader extends Thread {
  4.     private Lock readLock = null;
  5.     public Reader(Lock readLock) {
  6.         this.readLock = readLock;
  7.     }
  8.     public void run() {
  9.         while (true) {
  10.             readLock.lock();
  11.             try {
  12. System.out.println(Thread.currentThread().getName()
  13.                         + ":read action for 1 seconds-"+ReadWriteLock.testVal);
  14.             } finally {
  15.                 readLock.unlock();
  16.             }
  17.             try {
  18.                 Thread.sleep(1000);
  19.             } catch (InterruptedException e) {
  20.                 e.printStackTrace();
  21.             }
  22.         }
  23.     }
  24. }
  25. class Writer extends Thread {
  26.     private Lock writeLock = null;
  27.     public Writer(Lock writeLock) {
  28.         this.writeLock = writeLock;
  29.     }
  30.     public void run() {
  31.         while (true) {
  32.             writeLock.lock();
  33.             try {
  34. System.out.println(Thread.currentThread().getName()
  35.                         + ":write action for 2 seconds");
  36. if(ReadWriteLock.testVal.equals("1111"))
  37.                     ReadWriteLock.testVal = "2222";
  38.                 else
  39.                     ReadWriteLock.testVal = "1111";
  40.             } finally {
  41.                 writeLock.unlock();
  42.             }
  43.             try {
  44.                 Thread.sleep(2000);
  45.             } catch (InterruptedException e) {
  46.                 e.printStackTrace();
  47.             }
  48.         }
  49.     }
  50. }
  51. public class ReadWriteLock {
  52.     public static String  testVal = "Initiation";
  53.     public static void main(String[] args) {
  54.         ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
  55.         Lock readLock = lock.readLock();
  56.         Lock writeLock = lock.writeLock();
  57.         Reader reader1 = new Reader(readLock);
  58.         reader1.setName("reader1");
  59.         Reader reader2 = new Reader(readLock);
  60.         reader2.setName("reader2");
  61.         Reader reader3 = new Reader(readLock);
  62.         reader3.setName("reader3");
  63.         Reader reader4 = new Reader(readLock);
  64.         reader4.setName("reader4");
  65.         Writer writer = new Writer(writeLock);
  66.         writer.setName("writer1");
  67.         reader1.start();
  68.         reader2.start();
  69.         reader3.start();
  70.         reader4.start();
  71.         writer.start();
  72.     }
  73. }

輸出:

reader1:read action for 1 seconds-Initiation
reader3:read action for 1 seconds-Initiation
writer1:write action for 2 seconds
reader2:read action for 1 seconds-1111
reader4:read action for 1 seconds-1111
reader3:read action for 1 seconds-1111
reader1:read action for 1 seconds-1111
reader4:read action for 1 seconds-1111
reader2:read action for 1 seconds-1111
writer1:write action for 2 seconds
reader4:read action for 1 seconds-2222
reader1:read action for 1 seconds-2222
reader3:read action for 1 seconds-2222
reader2:read action for 1 seconds-2222

4、總結(jié)

Lock接口替代synchronized

Lock接口可以比sychronized提供更廣泛的鎖定操作,可以提供多把不同的鎖,且鎖之間互不干涉。

Lock接口提供lock()與unlock()方法,使用明確調(diào)用來(lái)完成同步的,OO思想好于前者。

Lock可以自由操控同步范圍(scope)。

Lock接口支持nested lock(嵌套鎖定),并提供了豐富的api。

Lock接口提供了tryLock()方法,支持嘗試取得某個(gè)object lock。


標(biāo)題名稱:去故就新Java線程新同步機(jī)制
文章起源:http://www.5511xx.com/article/dhpgojg.html