CountdownLacth CyclicBarrier Join
Join:main里面調(diào)用t1.join,阻塞main線程,直到t1線程結(jié)束,main線程繼續(xù)執(zhí)行.
countdownLacth:線程計數(shù)器,初始化時指定計數(shù)器數(shù)值,阻塞await線程,直到計數(shù)器為0,被阻塞的線程執(zhí)行,調(diào)用countDown()不會阻塞當前線程.
CyclicBarrier:多個線程同時阻塞在await處,當所有線程都執(zhí)行到await處時,所有await的線程同時往下執(zhí)行.
Join示例代碼
public class JoinTest {
public static void main(String[] args) {
System.out.println("進入主線程");
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
try {
System.out.println("t1線程開始執(zhí)行");
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("t1線程執(zhí)行完畢");
}
});
t1.start();
try {
System.out.println("主線程開始等待");
t1.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("主線程繼續(xù)執(zhí)行");
}
}
log信息
進入主線程
主線程開始等待
t1線程開始執(zhí)行
t1線程執(zhí)行完畢
主線程繼續(xù)執(zhí)行
countdownLacth示例
public class UseCountDownLatch {
public static void main(String[] args) {
//初始化countdownLatch時設置計數(shù)器數(shù)字,如果這個案例改成3,那么t1永遠在await
final CountDownLatch countDown = new CountDownLatch(2);
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
try {
System.out.println("進入線程t1" + "等待其他線程處理完成...");
countDown.await();
System.out.println("t1線程繼續(xù)執(zhí)行...");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"t1");
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
try {
System.out.println("t2線程初始化完畢颠区,2s后計數(shù)器減一...");
Thread.sleep(2000);
countDown.countDown();
System.out.println("t2繼續(xù)執(zhí)行,");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
Thread t3 = new Thread(new Runnable() {
@Override
public void run() {
try {
System.out.println("t3線程進行初始化操作,4s后計數(shù)器減一");
Thread.sleep(4000);
System.out.println("t3線程初始化完畢通铲,計數(shù)器減一...");
countDown.countDown();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
t1.start();
t2.start();
t3.start();
}
}
log信息
t2線程初始化完畢毕莱,2s后計數(shù)器減一...
t3線程進行初始化操作,4s后計數(shù)器減一
進入線程t1等待其他線程處理完成...
t2繼續(xù)執(zhí)行,
t3線程初始化完畢测暗,計數(shù)器減一...
t1線程繼續(xù)執(zhí)行...
CyclicBarrier代碼示例
public class CyclicBarrierTest {
static final CyclicBarrier barrier=new CyclicBarrier(3);
static class test implements Runnable{
@Override
public void run() {
try {
System.out.println("進入線程"+Thread.currentThread().getId()+"開始執(zhí)行任務");
Thread.sleep(3000);
System.out.println("線程"+Thread.currentThread().getId()+"進入等待");
barrier.await();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
System.out.println("線程"+Thread.currentThread().getId()+"開始執(zhí)行");
}
}
public static void main(String[] args) {
ExecutorService executor= Executors.newFixedThreadPool(3);
executor.submit(new test());
executor.submit(new test());
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
executor.submit(new test());
}
}
log信息
進入線程12開始執(zhí)行任務
進入線程11開始執(zhí)行任務
線程11進入等待
線程12進入等待
進入線程13開始執(zhí)行任務
線程13進入等待
線程13開始執(zhí)行
線程11開始執(zhí)行
線程12開始執(zhí)行
寫這個示例的時候犯蠢了,線程池初始的時候?qū)懥?“newFixedThreadPool(2)”, CyclicBarrier(3)計數(shù)器是3央串,開始執(zhí)行時卡住了 log信息如下
進入線程11開始執(zhí)行任務
進入線程12開始執(zhí)行任務
線程11進入等待
線程12進入等待
然后就不動了,仔細一想,線程池一共2條線程,全被await阻塞著,導致沒有線程執(zhí)行第三個任務了,形成了我等t3,t3等t1碗啄,t2線程釋放,死循壞.