????最近在項目中遇到需要開啟多個線程運行不同的功能肄渗,同時當(dāng)線程全部執(zhí)行完后才能執(zhí)行主線程的情況搞乏,在查找一些資料后有了相應(yīng)的解決方法扶欣,同時還有一些特殊情況需特殊處理仗考,現(xiàn)將處理過程記錄如下:
????對于這種線程問題大致可以使用CountDownLatch,jion词爬,F(xiàn)utureTask秃嗜,static變量,CyclicBarrier五中方法實現(xiàn):
1.static變量
????定義一個靜態(tài)變量顿膨,每當(dāng)一個線程執(zhí)行完后锅锨,static變量減一,當(dāng)static變量的值為1是執(zhí)行主線程恋沃,不過此時需要對static變量進行同步操作必搞。(這種方法最簡單,但并不好)
public class StaticThread implements Runnable{
public static int flag = 5;
public static void main(String[] args) {
Thread threads[] = new Thread[5];
for(Thread thread : threads) {
thread = new Thread(new StaticThread());
thread.start();
}
while(flag > 0) {
continue;
}
System.out.println("----- 所有線程執(zhí)行完畢");
}
@Override
public void run() {
System.out.println("當(dāng)前線程:" + Thread.currentThread().getName() + "啟動");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("當(dāng)前線程:" + Thread.currentThread().getName() + "結(jié)束");
synchronized ((Object)flag) {
flag-=1;
}
}
}
結(jié)果:
當(dāng)前線程:Thread-0啟動
當(dāng)前線程:Thread-1啟動
當(dāng)前線程:Thread-2啟動
當(dāng)前線程:Thread-0結(jié)束
當(dāng)前線程:Thread-3啟動
當(dāng)前線程:Thread-1結(jié)束
當(dāng)前線程:Thread-4啟動
當(dāng)前線程:Thread-2結(jié)束
當(dāng)前線程:Thread-3結(jié)束
當(dāng)前線程:Thread-4結(jié)束
----- 所有線程執(zhí)行完畢
2.CountDownLatch
????CountDownLatch類能夠?qū)崿F(xiàn)讓一個線程等待其他線程執(zhí)行完畢再執(zhí)行囊咏,主要是通過一個計數(shù)器來完成恕洲,初始值為線程數(shù),當(dāng)線程執(zhí)行完畢后計數(shù)器減一梅割, 直到計數(shù)器為0表示線程全部執(zhí)行完成霜第。
public class CountDownLatchThread implements Runnable {
//當(dāng)前計數(shù)器的值
public static CountDownLatch lock = new CountDownLatch(5);
public static void main(String[] args) {
Thread threads[] = new Thread[5];
for(Thread thread : threads) {
thread = new Thread(new CountDownLatchThread());
thread.start();
}
try {
//等待直至計數(shù)器為0
lock.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("----- 所有線程執(zhí)行完畢");
}
@Override
public void run() {
System.out.println("當(dāng)前線程:" + Thread.currentThread().getName() + "啟動");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("當(dāng)前線程:" + Thread.currentThread().getName() + "結(jié)束");
//線程執(zhí)行完畢,調(diào)用計數(shù)器countDown()方法減1
lock.countDown();
}
}
結(jié)果:
當(dāng)前線程:Thread-4啟動
當(dāng)前線程:Thread-4結(jié)束
當(dāng)前線程:Thread-2啟動
當(dāng)前線程:Thread-2結(jié)束
當(dāng)前線程:Thread-1啟動
當(dāng)前線程:Thread-1結(jié)束
當(dāng)前線程:Thread-3啟動
當(dāng)前線程:Thread-3結(jié)束
當(dāng)前線程:Thread-0啟動
當(dāng)前線程:Thread-0結(jié)束
----- 所有線程執(zhí)行完畢
實際項目遇到的問題:
一旦run()方法中的實現(xiàn)在lock.countDown()方法前調(diào)用了return方法户辞,程序?qū)⒉粫蛳聢?zhí)行泌类,不得不在return之前再次調(diào)用lock.countDown()方法。(和staitc相似)
3.join
????join方法是等待該線程死亡底燎。
????每個線程都跳用join方法即可刃榨。
比較麻煩,同時調(diào)用的地方需要注意双仍,否則可能會出現(xiàn)依次執(zhí)行的情況枢希。
4.FutureTask
5.CyclicBarrier