一、如何實現子線程執行完畢再執行主線程?
很多時候在代碼的實現過程中,我們想子線程全部運行完成後,再運行主線程後面的流程,如何進行,請看下面兩種方法
先看沒有處理的情況如下:
public class DoRunnable {
public static void thread() throws InterruptedException{
for(int i = 0; i < 10; i++) {
Thread t2 = new Thread(new Runnable() {
public void run() {
System.out.println("<<<<<<<<<<<<"+ "function1-2:" + Thread.currentThread().getName() + "<<<<<<<<<<<"+ System.currentTimeMillis()+"" +"<<<<<<<<<<<");
countDownLatch.countDown();
}
});
t2.start();
}
}
public static void main(String[] args) throws InterruptedException {
thread();
System.out.println("*******************************end*******************************");
}
}
結果:
<<<<<<<<<<<<function1-2:Thread-2<<<<<<<<<<<1565261950647<<<<<<<<<<<
<<<<<<<<<<<<function1-2:Thread-3<<<<<<<<<<<1565261950647<<<<<<<<<<<
*******************************end*******************************
<<<<<<<<<<<<function1-2:Thread-1<<<<<<<<<<<1565261950647<<<<<<<<<<<
<<<<<<<<<<<<function1-2:Thread-0<<<<<<<<<<<1565261950647<<<<<<<<<<<
<<<<<<<<<<<<function1-2:Thread-7<<<<<<<<<<<1565261950648<<<<<<<<<<<
<<<<<<<<<<<<function1-2:Thread-6<<<<<<<<<<<1565261950648<<<<<<<<<<<
<<<<<<<<<<<<function1-2:Thread-4<<<<<<<<<<<1565261950648<<<<<<<<<<<
<<<<<<<<<<<<function1-2:Thread-5<<<<<<<<<<<1565261950648<<<<<<<<<<<
<<<<<<<<<<<<function1-2:Thread-8<<<<<<<<<<<1565261950649<<<<<<<<<<<
<<<<<<<<<<<<function1-2:Thread-9<<<<<<<<<<<1565261950649<<<<<<<<<<<
1.Join
public class DoRunnable {
public static void thread() throws InterruptedException{
for(int i = 0; i < 10; i++) {
Thread t2 = new Thread(new Runnable() {
public void run() {
System.out.println("<<<<<<<<<<<<"+ "function1-2:" + Thread.currentThread().getName() + "<<<<<<<<<<<"+ System.currentTimeMillis()+"" +"<<<<<<<<<<<");
}
});
t2.start();
t2.join();
}
}
public static void main(String[] args) throws InterruptedException {
thread();
System.out.println("*******************************end*******************************");
}
}
結果:
<<<<<<<<<<<<function1-2:Thread-0<<<<<<<<<<<1565262169575<<<<<<<<<<<
<<<<<<<<<<<<function1-2:Thread-1<<<<<<<<<<<1565262169576<<<<<<<<<<<
<<<<<<<<<<<<function1-2:Thread-2<<<<<<<<<<<1565262169576<<<<<<<<<<<
<<<<<<<<<<<<function1-2:Thread-3<<<<<<<<<<<1565262169576<<<<<<<<<<<
<<<<<<<<<<<<function1-2:Thread-4<<<<<<<<<<<1565262169577<<<<<<<<<<<
<<<<<<<<<<<<function1-2:Thread-5<<<<<<<<<<<1565262169577<<<<<<<<<<<
<<<<<<<<<<<<function1-2:Thread-6<<<<<<<<<<<1565262169577<<<<<<<<<<<
<<<<<<<<<<<<function1-2:Thread-7<<<<<<<<<<<1565262169578<<<<<<<<<<<
<<<<<<<<<<<<function1-2:Thread-8<<<<<<<<<<<1565262169578<<<<<<<<<<<
<<<<<<<<<<<<function1-2:Thread-9<<<<<<<<<<<1565262169578<<<<<<<<<<<
*******************************end*******************************
2.CountDownLatch
public class DoRunnable {
public static void thread() throws InterruptedException{
CountDownLatch countDownLatch = new CountDownLatch(10);
for(int i = 0; i < 10; i++) {
Thread t2 = new Thread(new Runnable() {
public void run() {
System.out.println("<<<<<<<<<<<<"+ "function1-2:" + Thread.currentThread().getName() + "<<<<<<<<<<<"+ System.currentTimeMillis()+"" +"<<<<<<<<<<<");
countDownLatch.countDown();
}
});
t2.start();
}
countDownLatch.await();
}
public static void main(String[] args) throws InterruptedException {
thread();
System.out.println("*******************************end*******************************");
}
}
結果:
<<<<<<<<<<<<function1-2:Thread-0<<<<<<<<<<<1565262078875<<<<<<<<<<<
<<<<<<<<<<<<function1-2:Thread-3<<<<<<<<<<<1565262078875<<<<<<<<<<<
<<<<<<<<<<<<function1-2:Thread-1<<<<<<<<<<<1565262078875<<<<<<<<<<<
<<<<<<<<<<<<function1-2:Thread-2<<<<<<<<<<<1565262078875<<<<<<<<<<<
<<<<<<<<<<<<function1-2:Thread-4<<<<<<<<<<<1565262078876<<<<<<<<<<<
<<<<<<<<<<<<function1-2:Thread-5<<<<<<<<<<<1565262078876<<<<<<<<<<<
<<<<<<<<<<<<function1-2:Thread-6<<<<<<<<<<<1565262078876<<<<<<<<<<<
<<<<<<<<<<<<function1-2:Thread-7<<<<<<<<<<<1565262078876<<<<<<<<<<<
<<<<<<<<<<<<function1-2:Thread-9<<<<<<<<<<<1565262078876<<<<<<<<<<<
<<<<<<<<<<<<function1-2:Thread-8<<<<<<<<<<<1565262078876<<<<<<<<<<<
*******************************end*******************************
總結:
沒處理之前,主線程和子線程混合進行。子線程全部運行完成後,再運行主線程後面的流程有兩種方法:join和countdownlatch。
join方法實現在t.start之後。阻止主線程活動
countdownlatch方法,需要先實例化,入參帶上子線程個數,然後run()執行體中實現countDownLatch.countDown()減1操作,最後在所有子線程循環體外進行countDownLatch.await()。靠計數器保證主線程活動
二、資源不夠導致線程阻塞,如何提高線程安全性?
時間有限,可參考線程池 ExecutorService詳解,具體內容後續補充。。。
三、線程狀態之間的各種轉換是如何實現的?
四、如何獲取子線程返回值?
方法一:callable和futuretask的線程實現方法,具體詳見https://blog.csdn.net/zhouping19851013/article/details/98764627
方法二:子線程run方法中加入存數據庫操作,主線程加入延時等待Thread.sleep(time)讀取數據庫
方法三:線程池 ExecutorService 暫不介紹,詳細介紹後續補充