標籤:
1. Semaphore
訊號量是一種計數器,用來保護一個或者多個共用資源的訪問。如果線程要訪問一個共用資源,必須先獲得訊號量。若內部計數器大於0,則減1,若等於0,則線程進入休眠直至計數器大於等於0。
Semaphore semaphore1 = new Semaphore(1); // 值為1的訊號量Semaphore semaphore2 = new Semaphore(1, true); // 公平模式,FIFOsemaphore1.acquire(); // 擷取資源,否則阻塞,且在阻塞過程中可以被中斷semaphore1.acquireUninterruptibly(); // 擷取資源,否則阻塞,且在阻塞過程中不可被中斷semaphore1.tryAcquire(); // 嘗試擷取semaphore1.release(); // 釋放
2. CountDownLatch
CountDownLatch是一個同步輔助類,在完成一組正在其他線程中執行的操作之前,它允許線程一直等待。若一個線程需要等待某些操作先執行完,需調用await()方法進入休眠,當一個操作完成,則調用countDown()將內部計數器減1,若變為0時,則喚醒所有因調用await()而進入休眠的線程。
CountDownLatch機制不是用來保護共用資源或者臨界區的,它是用來同步執行多個任務的一個或者多個線程。
CountDownLatch不能被重設。
CountDownLatch controller = new CountDownLatch(number); // 計數器為numbercontroller.countDown(); // 計數器減1controller.getCount(); // 擷取計數器的值controller.await(); // 等待計數器變0
3. CyclicBarrier
CyclicBarrier是一個同步輔助類,它允許兩個或者多個線程在某個點上進行同步。當一個線程到達指定的點後,調用await()方法休眠並等待其他的線程,當最後一個的await()方法被調用時,CyclicBarrier將喚醒所有在等待的線程然後這些線程將繼續執行。
CyclicBarrier還可以傳入另一個Runnable對象作為之後啟動並執行線程。
CyclicBarrier可以被重設。
CyclicBarrier barrier = new CyclicBarrier(5, task); // 需要集合5個線程,並且之後運行taskbarrier.await(); // 休眠等待barrier.await(long, TimeUnit); // 保持休眠直到被中斷。或者內部計數器變為0,或者時間到期barrier.getNumberWaiting(); // 返回阻塞線程數目barrier.getParties(); // 返回對象同步的任務數barrier.reset(); // 重設對象,await()的線程拋出一個BrokenBarrierExceptionbarrier.isBroken(); // 判斷對象是否損壞,這種狀態在其中一個線程被中斷拋出InterruptedException時出現
4. Phaser
一個輔助類,允許執行並發多階段任務,在每一步結束時對線程進行同步。
需要對同步操作的任務數進行初始化,但是可以動態地增加或者減少任務數。
Phaser不會被中斷響應。
Phaser phaser = new Phaser(3); // 需要3個線程同步phaser.arriveAndAwaitActive(); // 等待3個線程到達此執行點phaser.arriveAndDeregister(); // 減少一個需要同步的線程phaser.onAdvance(); // 返回true則說明處於終止態phaser.isFinalized();
Phaser還提供其他改變對象的方法。
Phaser phaser = new Phaser(3); // 需要3個線程同步phaser.arrive(); // 通知一個參與者已經完成了當前階段,不應該等待其他參與者,故不會同步phaser.awaitAdvance(int); // 若傳入參數與當前階段一致,則當前線程休眠直到這個階段參與者都完成;否則立即返回phaser.awaitAdvanceInterruptibly(int); // 若被中斷拋出異常phaser.register(); // 註冊一個新的參與者phaser.register(int); // 大量註冊phaser.forceTermination(); // 強制終止
5. Exchanger
一個輔助類,允許在兩個線程之間定義同步點,當兩個線程都到達同步點時,交換他們的資料結構。
Exchanger<List<String>> exchanger = new Exchanger<List<String>>();List<String> buffer = new List<String>();buffer = exchanger.exchange(buffer);
Java並發編程小記