常用的輔助類
CountDownLatch
這是一個JUC計數器輔助類,計數器有加有減,這是減。
使用方法
package org.example.demo;
import java.util.concurrent.CountDownLatch;
//執行緒計數器
public class CountDownLatchDemo {
public static void main(String[] args) {
CountDownLatch countDownLatch = new CountDownLatch(6);//總數為6,必須要執行任務時用
for (int i = 0; i < 6; i++) {
new Thread(()->{
System.out.println(Thread.currentThread().getName()+" go out");
countDownLatch.countDown();//總數減1
},String.valueOf(i)).start();
}
try {
countDownLatch.await();//等待總數變為0才會往下執行,相當於阻塞當前執行緒
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.out.println("關門");
}
}
使用前
可能會在所有人沒出去之前關門
使用後
不在乎誰先出去,但是一定要總數等於0後才會關門
原理
countDownLatch.countDown();//總數減1
countDownLatch.await();//等待總數變為0才會往下執行,相當於阻塞當前執行緒
每次有執行緒呼叫countDown() 數量減一,假設計數器變為0,await()就會被喚醒,繼續執行!
CyclicBarrier
有減法就有加法
使用方法略有不同,一是新增了達到數量後可以執行一個方法,二十await方法放在了執行緒的內部
package org.example.demo;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
public class CyclicBarrierDemo {
public static void main(String[] args) {
CyclicBarrier cyclicBarrier = new CyclicBarrier(7,()->{
System.out.println("召喚神龍成功");//在達到數量後執行一個Runnable介面方法
});
for (int i = 1; i <= 7; i++) {
//lambda表示式本質上還是new了一個類,所以無法直接拿到for迴圈中的變數i,需要透過一個臨時變數final來作為一箇中間變數來獲取到i
final int temp = i;
new Thread(()->{
System.out.println(Thread.currentThread().getName()+":獲取到了"+temp+"顆龍珠");
try {
cyclicBarrier.await();//每次等待完成後往下執行,如果達不到數量會死在這
} catch (InterruptedException e) {
throw new RuntimeException(e);
} catch (BrokenBarrierException e) {
throw new RuntimeException(e);
}
},String.valueOf(i)).start();
}
}
}
Semaphore
Semaphore:訊號量
搶車位:6輛車3個車位,123佔據了那麼456就需要等待,當佔據的車走後,那麼等待的車就要進入該車位。
用於限流等操作
package org.example.demo;
import java.sql.Time;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
public class SemaphoreDemo {
public static void main(String[] args) {
// 執行緒數量:限流!讓沒有得到的等待釋放
Semaphore sim = new Semaphore(3);
for (int i = 0; i < 6; i++) {
new Thread(()->{
//acquire 得到
//release 釋放
try {
sim.acquire();
System.out.println(Thread.currentThread().getName()+":搶到車位");
TimeUnit.SECONDS.sleep(2);
System.out.println(Thread.currentThread().getName()+":離開車位");
} catch (InterruptedException e) {
throw new RuntimeException(e);
}finally {//所有需要關閉、釋放的操作都放在finally中
sim.release();
}
}).start();
}
}
}
sim.acquire();//得到
sim.release();//釋放
作用:多個共享資源互斥的使用!併發限流,控制最大執行緒數!