java 主執行緒等待子執行緒執行完後再執行
阿新 • • 發佈:2018-12-31
這裡記錄一下下面這種情況:主執行緒需要等待多個子執行緒執行完後再執行。
我們先看一下下面的場景:
package com.java4all.mypoint;
import java.util.concurrent.CountDownLatch;
/**
* Author: yunqing
* Date: 2018/7/18
* Description:執行緒測試
* 測試點:主執行緒等待子執行緒全部執行完後再執行
*/
public class ThreadTest {
public static void main(String[] args)throws Exception{
System.out.println("主執行緒正在執行前:" +Thread.currentThread().getName());
test3();
System.out.println("主執行緒正在執行後:"+Thread.currentThread().getName());
}
public static void test3(){
try {
for (int i = 1 ;i <= 10;i ++){
Thread.sleep(1000);
new Thread(()->{
System.out.println("子執行緒正在執行:" +Thread.currentThread().getName());
}).start();
}
}catch (Exception ex){
ex.printStackTrace();
}
}
}
執行結果為:
主執行緒正在執行前:main
子執行緒正在執行:Thread-0
子執行緒正在執行:Thread-1
子執行緒正在執行:Thread-2
子執行緒正在執行:Thread-3
子執行緒正在執行:Thread-4
子執行緒正在執行:Thread-5
子執行緒正在執行:Thread- 6
子執行緒正在執行:Thread-7
子執行緒正在執行:Thread-8
主執行緒正在執行後:main
子執行緒正在執行:Thread-9
可以看到,子執行緒還沒執行完時,主執行緒進來了。
1.使用CountDownLatch
示例如下,我們初始化一個CountDownLatch,值為10(子執行緒個數),然後每次一個子執行緒執行完後執行一下countDown(),程式碼示例如下:
package com.java4all.mypoint;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
/**
* Author: yunqing
* Date: 2018/7/18
* Description:執行緒測試
* 測試點:主執行緒等待子執行緒全部執行完後再執行
*/
public class ThreadTest {
/**初始化CountDownLatch,值為執行緒數量*/
private static final CountDownLatch ctl = new CountDownLatch(10);
public static void main(String[] args)throws Exception{
System.out.println("主執行緒正在執行前:"+Thread.currentThread().getName());
test3();
ctl.await(20, TimeUnit.SECONDS);//最多等待20秒,不管子執行緒完沒完
System.out.println("主執行緒正在執行後:"+Thread.currentThread().getName());
}
public static void test3(){
try {
for (int i = 1 ;i <= 10;i ++){
Thread.sleep(1000);
new Thread(()->{
System.out.println("子執行緒正在執行:"+Thread.currentThread().getName());
}).start();
ctl.countDown();
}
}catch (Exception ex){
ex.printStackTrace();
}
}
}
執行結果為:
主執行緒正在執行前:main
子執行緒正在執行:Thread-0
子執行緒正在執行:Thread-1
子執行緒正在執行:Thread-2
子執行緒正在執行:Thread-3
子執行緒正在執行:Thread-4
子執行緒正在執行:Thread-5
子執行緒正在執行:Thread-6
子執行緒正在執行:Thread-7
子執行緒正在執行:Thread-8
子執行緒正在執行:Thread-9
主執行緒正在執行後:main
或者用java8之前的方式寫:
執行緒類:
package com.java4all.mypoint;
import java.util.concurrent.CountDownLatch;
/**
* Author: yunqing
* Date: 2018/7/23
* Description:
*/
public class MyRunnable implements Runnable{
public CountDownLatch countDownLatch;
@Override
public void run() {
try {
Thread.sleep(2000);
System.out.println("子執行緒正在執行任務,當前執行緒為:"+Thread.currentThread().getName());
}catch (InterruptedException inex){
inex.printStackTrace();
}finally {
countDownLatch.countDown();
}
}
public CountDownLatch getCountDownLatch() {
return countDownLatch;
}
public void setCountDownLatch(CountDownLatch countDownLatch) {
this.countDownLatch = countDownLatch;
}
}
測試類:
package com.java4all.mypoint;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
/**
* Author: yunqing
* Date: 2018/7/18
* Description:執行緒測試
* 測試點:主執行緒等待子執行緒全部執行完後再執行
*/
public class ThreadTest {
/**初始化CountDownLatch,值為執行緒數量*/
private static final CountDownLatch ctl = new CountDownLatch(10);
public static void main(String[] args)throws Exception{
System.out.println("主執行緒正在執行前:"+Thread.currentThread().getName());
for(int i = 1;i <= 10;i ++){
MyRunnable runnable = new MyRunnable();
runnable.setCountDownLatch(ctl);
Thread thread = new Thread(runnable);
thread.start();
}
ctl.await(20, TimeUnit.SECONDS);//最多等待20秒,不管子執行緒完沒完
System.out.println("主執行緒正在執行後:"+Thread.currentThread().getName());
}
}
結果為:
主執行緒正在執行前:main
子執行緒正在執行任務,當前執行緒為:Thread-1
子執行緒正在執行任務,當前執行緒為:Thread-0
子執行緒正在執行任務,當前執行緒為:Thread-2
子執行緒正在執行任務,當前執行緒為:Thread-3
子執行緒正在執行任務,當前執行緒為:Thread-4
子執行緒正在執行任務,當前執行緒為:Thread-7
子執行緒正在執行任務,當前執行緒為:Thread-6
子執行緒正在執行任務,當前執行緒為:Thread-5
子執行緒正在執行任務,當前執行緒為:Thread-9
子執行緒正在執行任務,當前執行緒為:Thread-8
主執行緒正在執行後:main
附:
開啟一個執行緒的其他寫法:
/**jdk7匿名內部類的寫法*/
public static void test1(){
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("aaaa");
}
}).start();
}
/**
* jdk8
* Runnable是個函式介面,可以利用jdk8的lambda來簡寫
* 函式介面:是指內部只有一個抽象方法的介面
* */
public static void test2(){
new Thread(()->{
System.out.println("bbb");
}).start();
}