1.CountDownLatch (線程計數器)
利用CountDownLatch 可以實現類似計數器的功能,比如主線程需要等待5個子線程執行完畢之後才能執行,就可以利用CountDownLatch實現,案例如下:
public class TestThread {
final static CountDownLatch latch = new CountDownLatch(5); //如果大於num將會造成一直等待
public static void main(String[] args) throws InterruptedException {
//線程數
int num = 5;
MyRunnable myRunnable = new MyRunnable();
for(int i=0;i<5;i++){
new Thread(myRunnable).start();
}
latch.await();
System.out.println("主線程了");
}
}
class MyRunnable implements Runnable{
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"我是run方法");
TestThread.latch.countDown();
}
}
執行結果:
2.CyclicBarrier(迴環柵欄)
迴環柵欄的作用就是整合一組線程,在這一組線程全部達到某個狀態之後同時執行,其最重要的方法爲await()
1. public int await():用來掛起當前線程,直至所有線程都到達 barrier 狀態再同時執行後續任
務;
2. public int await(long timeout, TimeUnit unit):讓這些線程等待至一定的時間,如果還有
線程沒有到達 barrier 狀態就直接讓到達 barrier 的線程執行後續任務。
案例:
public class TestThread {
public static void main(String[] args) throws InterruptedException {
//線程數
int num = 5;
CyclicBarrier cb = new CyclicBarrier(5); //如果大於num將會造成一直等待
MyRunnable myRunnable = new MyRunnable(cb);
for(int i=0;i<num;i++){
new Thread(myRunnable).start();
}
}
}
class MyRunnable implements Runnable{
private CyclicBarrier cb;
public MyRunnable(){}
public MyRunnable(CyclicBarrier cb){
this.cb = cb;
}
@Override
public void run() {
try {
Thread.sleep(1000);
System.out.println("業務代碼操作完成,等待其他線程執行完畢");
cb.await();
System.out.println("所有線程執行完畢");
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
}
}
執行結果:
3.Semaphore(信號量)
Semaphore可以控制同時訪問的線程個數,通過acquire() 獲取一個許可,如果沒有就等待,而 release() 釋放一個許可。
案例:
public class TestThread {
final static int S_NUM = 1;
final static Semaphore SP = new Semaphore(S_NUM);
public static void main(String[] args) throws InterruptedException {
//線程數
int num = 5;
MyRunnable myRunnable = new MyRunnable();
for(int i=0;i<num;i++){
new Thread(myRunnable).start();
}
}
}
class MyRunnable implements Runnable{
@Override
public void run() {
try {
TestThread.SP.acquire();
System.out.println(Thread.currentThread().getName()+"在執行start");
Thread.sleep(1000);
System.out.println(Thread.currentThread().getName()+"在執行end");
TestThread.SP.release();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
執行結果(S_NUM=1時):
執行結果(S_NUM=2時):
由S_NUM=2可以看出Semaphore可以控制線程同時執行數量。