1. 程式人生 > >Java執行緒之閉鎖

Java執行緒之閉鎖

 閉鎖是一種同步工具類,可以延遲執行緒的進度直到其到達終止狀態。閉鎖的作用相當於一扇門:在閉鎖到達結束狀態之前,這扇門一直是關閉的,並且沒有任何執行緒能通過,當到達結束狀態時,這扇門會開啟並允許所有的執行緒通過。當閉鎖到達結束狀態後,將不會再改變狀態,因此這扇門將永遠保持開啟狀態。閉鎖可以用來確保某些活動直到其他活動都完成後才繼續執行,例如:

  • 確保某個計算再其需要的所有資源都被初始化之後才繼續執行。二元閉鎖(包括兩個狀態)可以用來表示“資源R已經被初始化”,而所有需要R的操作都必須先在這個閉鎖上等待。
  • 確保某個服務在其依賴的所有其他服務都已經啟動之後才啟動。每個服務都有一個相關的二元閉鎖。每當啟動服務S時,將首先在S依賴的其他服務的閉鎖上等待,在所有依賴的服務都啟動後會釋放閉鎖S,這樣其他依賴S的服務才能繼續執行。
  • 等待直到某個操作的所有參與者(例如,在多玩家遊戲中的所有玩家)都就緒時,閉鎖將到達結束狀態。

CountDownLatch是一種靈活的閉鎖實現,可以在上述情況中使用,它可以使一個或多個執行緒等待一組事件發生。閉鎖狀包括一個計數器,該計數器被初始化為一個正數,表示需要等待的事件數量。countDown方法遞減計數器,表示有一個事件已經發生了,而await方法等待計數器達到零,這表示所有需要等待的事件都已經發生。如果計數器的值為非零,那麼await會在一直阻塞直到計數器為零。或者等待中的執行緒中斷,或者等待超時。

public static long timeTTasks(
int nThreads, final Runnable task) throws InterruptedException { final CountDownLatch startGate = new CountDownLatch(1);//傳入計數器的大小 final CountDownLatch endGate = new CountDownLatch(nThreads); for (int i = 0; i < nThreads; i++) { Thread t = new Thread(new Runnable(
) { @Override public void run() { try { System.out.println("name:"+Thread.currentThread().getName()+"開始等待"); startGate.await();//等待 System.out.println("name:"+Thread.currentThread().getName()+"開始執行"); try { task.run(); } finally { endGate.countDown();//計數器減一 } } catch (InterruptedException e) { e.printStackTrace(); } } }); t.start(); } long start = System.nanoTime(); Thread.sleep(3000); System.out.println("釋放startGate"); startGate.countDown();//計數器減一 endGate.await();//等待 long end = System.nanoTime(); return end - start; }