国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|JAVA教程|ASP教程|編程技術|

服務器之家 - 編程語言 - JAVA教程 - Java多線程--讓主線程等待所有子線程執行完畢在執行

Java多線程--讓主線程等待所有子線程執行完畢在執行

2020-07-02 11:29yadsun JAVA教程

Java主線程等待所有子線程執行完畢在執行,其實在我們的工作中經常的用到,本篇文章就介紹了Java多線程--讓主線程等待所有子線程執行完畢在執行,有需要的可以了解一下。

朋友讓我幫忙寫個程序從文本文檔中導入數據到oracle數據庫中,技術上沒有什么難度,文檔的格式都是固定的只要對應數據庫中的字段解析就行了,關鍵在于性能。

數據量很大百萬條記錄,因此考慮到要用多線程并發執行,在寫的過程中又遇到問題,我想統計所有子進程執行完畢總共的耗時,在第一個子進程創建前記錄當前時間用System.currentTimeMillis()在最后一個子進程結束后記錄當前時間,兩次一減得到的時間差即為總共的用時,代碼如下 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
long tStart = System.currentTimeMillis();
System.out.println(Thread.currentThread().getName() + "開始");//打印開始標記
for (int ii = 0; ii < threadNum; ii++) {//開threadNum個線程
Runnable r = new Runnable(){
@Override
public void run(){
System.out.println(Thread.currentThread().getName() + "開始");
//做一些事情... ...
System.out.println(Thread.currentThread().getName() + "結束.");
}
}
Thread t = new Thread(r);
t.start();
}
System.out.println(Thread.currentThread().getName() + "結束.");//打印結束標記
long tEnd = System.currentTimeMillis();
System.out.println("總共用時:"+ (tEnd - tStart) + "millions");

結果是幾乎在for循環結束的瞬間就執行了主線程打印總共用時的語句,原因是所有的子線程是并發執行的,它們運行時主線程也在運行,這就引出了一個問題即本文標題如何"讓主線程等待所有子線程執行完畢"。試過在每個子線程開始后加上t.join(),結果是所有線程都順序執行,這就失去了并發的意義了,顯然不是我想要的。 

網上Google了很久也沒有找到解決方案,難道就沒有人遇到過這種需求嗎?還是這個問題太簡單了?無耐只得自己想辦法了... 

最后我的解決辦法是,自定義一個ImportThread類繼承自java.lang.Thread,重載run()方法,用一個List屬性保存所有產生的線程,這樣只要判斷這個List是否為空就知道還有沒有子線程沒有執行完了,類代碼如下: 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
public class ImportThread extends Thread {
private static List<Thread> runningThreads = new ArrayList<Thread>();
public ImportThread() {
}
@Override
public void run() {
regist(this);//線程開始時注冊
System.out.println(Thread.currentThread().getName() + "開始...");//打印開始標記
//做一些事情... ...
unRegist(this);//線程結束時取消注冊
System.out.println(Thread.currentThread().getName() + "結束.");//打印結束標記
}
public void regist(Thread t){
  synchronized(runningThreads){ 
    runningThreads.add(t);
  }
}
public void unRegist(Thread t){
  synchronized(runningThreads){ 
    runningThreads.remove(t);
  }
}
public static boolean hasThreadRunning() {
return (runningThreads.size() > 0);//通過判斷runningThreads是否為空就能知道是否還有線程未執行完
}
}

主線程中代碼: 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
long tStart = System.currentTimeMillis();
System.out.println(Thread.currentThread().getName() + "開始");//打印開始標記
for (int ii = 0; ii < threadNum; ii++) {//開threadNum個線程
Thread t = new ImportThread();
t.start();
}
while(true){//等待所有子線程執行完
if(!ImportThread.hasThreadRunning()){
break;
}
Thread.sleep(500);
}
System.out.println(Thread.currentThread().getName() + "結束.");//打印結束標記
long tEnd = System.currentTimeMillis();
System.out.println("總共用時:"+ (tEnd - tStart) + "millions");

打印的結果是: 

main開始 
Thread-1開始... 
Thread-5開始... 
Thread-0開始... 
Thread-2開始... 
Thread-3開始... 
Thread-4開始... 
Thread-5結束. 
Thread-4結束. 
Thread-2結束. 
Thread-0結束. 
Thread-3結束. 
Thread-1結束. 
main結束.          

總共用時:20860millions 

可以看到main線程是等所有子線程全部執行完后才開始執行的。 

================================================================================================= 

上面的方法有一個隱患:如果線程1開始并且結束了,而其他線程還沒有開始此時runningThreads的size也為0,主線程會以為所有線程都執行完了。解決辦法是用一個非簡單類型的計數器來取代List型的runningThreads,并且在線程創建之前就應該設定好計數器的值。 

MyCountDown類 
 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
  public class MyCountDown {
private int count;
public MyCountDown(int count){
this.count = count;
}
public synchronized void countDown(){
count--;
}
public synchronized boolean hasNext(){
return (count > 0);
}
public int getCount() {
return count;
}
public void setCount(int count) {
this.count = count;
}
}

ImportThread類 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
public class ImportThread extends Thread {
private MyCountDown c;
public ImportThread(MyCountDown c) {
this.c = c;
}
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + "開始...");//打印開始標記
//Do something
c.countDown();//計時器減1
System.out.println(Thread.currentThread().getName() + "結束. 還有" + c.getCount() + " 個線程");//打印結束標記
}
}

主線程中 

?
1
2
3
4
5
6
7
8
9
10
System.out.println(Thread.currentThread().getName() + "開始");//打印開始標記
MyCountDown c = new MyCountDown(threadNum);//初始化countDown
for (int ii = 0; ii < threadNum; ii++) {//開threadNum個線程
Thread t = new ImportThread(c);
t.start();
}
while(true){//等待所有子線程執行完
if(!c.hasNext()) break;
}
System.out.println(Thread.currentThread().getName() + "結束.");//打印結束標記

打印結果: 

 main開始 
Thread-2開始... 
Thread-1開始... 
Thread-0開始... 
Thread-3開始... 
Thread-5開始... 
Thread-4開始... 
Thread-5結束. 還有5 個線程 
Thread-1結束. 還有4 個線程 
Thread-4結束. 還有3 個線程 
Thread-2結束. 還有2 個線程 
Thread-3結束. 還有1 個線程 
Thread-0結束. 還有0 個線程 
main結束. 

更簡單的方法:使用java.util.concurrent.CountDownLatch代替MyCountDown,用await()方法代替while(true){...}

ImportThread類 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
public class ImportThread extends Thread {
private CountDownLatch threadsSignal;
public ImportThread(CountDownLatch threadsSignal) {
this.threadsSignal = threadsSignal;
}
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + "開始...");
//Do somethings
threadsSignal.countDown();//線程結束時計數器減1
System.out.println(Thread.currentThread().getName() + "結束. 還有" + threadsSignal.getCount() + " 個線程");
}
}

主線程中 

?
1
2
3
4
5
6
7
8
CountDownLatch threadSignal = new CountDownLatch(threadNum);//初始化countDown
for (int ii = 0; ii < threadNum; ii++) {//開threadNum個線程
final Iterator<String> itt = it.get(ii);
Thread t = new ImportThread(itt,sql,threadSignal);
t.start();
}
threadSignal.await();//等待所有子線程執行完
System.out.println(Thread.currentThread().getName() + "結束.");//打印結束標記

打印結果: 

main開始 
Thread-1開始... 
Thread-0開始... 
Thread-2開始... 
Thread-3開始... 
Thread-4開始... 
Thread-5開始... 
Thread-0結束. 還有5 個線程 
Thread-1結束. 還有4 個線程 
Thread-4結束. 還有3 個線程 
Thread-2結束. 還有2 個線程 
Thread-5結束. 還有1 個線程 
Thread-3結束. 還有0 個線程 
main結束.

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持服務器之家。

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 伊人网在线视频免费观看 | 91在线视频观看 | 日韩中文字幕在线观看 | 日日夜夜精品免费视频 | 欧美精品一区在线 | 欧美日韩综合在线 | 北条麻妃一区二区三区中文字幕 | 玖玖精品 | 婷婷激情五月 | 成人av一区二区三区 | 欧洲亚洲精品久久久久 | 日韩在线| 黄色在线免费 | 亚洲一区在线视频 | 伊人电影综合网 | 国产片在线播放 | 中国大陆高清aⅴ毛片 | 国产男女做爰免费网站 | 日本手机在线视频 | 农村末发育av片四区五区 | 中文字幕亚洲视频 | 亚洲精品在线观看av | 色爱区成人综合网 | 亚洲射情 | 美女久久久 | 亚洲小视频 | 国产精品日本 | 欧美一区二区高清视频 | 久久久婷婷 | 91精品国产色综合久久不卡蜜臀 | 99久久夜色精品国产网站 | 激情小视频 | 久久久国产一区二区三区 | 2023国产精品久久久精品双 | 日韩乱视频 | 性色综合 | 日韩电影免费观看 | 成人中文网 | 色香阁99久久精品久久久 | 国产精品久久久精品 | 久久久久久99精品 |