【转载】Java多线程,判断其他线程是否结束的三种方法

Java多线程,判断其他线程是否结束的三种方法

 
方法1:thread.Join把指定的线程加入到当前线程,可以将两个交替执行的线程合并为顺序执行的线程。

比如在线程B中调用了线程A的Join()方法,直到线程A执行完毕后,才会继续执行线程B。

t.join();      //调用join方法,等待线程t执行完毕
t.join(1000);  //等待 t 线程,等待时间是1000毫秒。

 

 1 public class TestJoin implements Runnable {
 2 
 3 
 4     public static void main(String[] sure) throws InterruptedException {
 5         Thread t = new Thread(new TestJoin());
 6         long start = System.currentTimeMillis();
 7         t.start();
 8         t.join(1000);//等待线程t 1000毫秒
 9         System.out.println(System.currentTimeMillis()-start);//打印出时间间隔
10         System.out.println("Main finished");//打印主线程结束
11     }
12 
13     @Override
14     public void run() {
15        // synchronized (currentThread()) {
16             for (int i = 1; i <= 5; i++) {
17                 try {
18                     sleep(1000);//睡眠5秒,循环是为了方便输出信息
19                 } catch (InterruptedException e) {
20                     e.printStackTrace();
21                 }
22                 System.out.println("睡眠" + i);
23             }
24             System.out.println("TestJoin finished");//t线程结束
25         }
26     //}
27 }
View Code

 

方法2:通过同步类CountDownLatch判断当前线程的线程组中活动线程的数目,为0时其他线程运行完毕。

同步辅助类:

    CountDownLatch是一个同步辅助类,在jdk5中引入,它允许一个或多个线程等待其他线程操作完成之后才执行。    

实现原理 :

    CountDownLatch是通过计数器的方式来实现,计数器的初始值为线程的数量。每当一个线程完成了自己的任务之后,就会对计数器减1,当计数器的值为0时,表示所有线程完成了任务,此时等待在闭锁上的线程才继续执行,从而达到等待其他线程完成任务之后才继续执行的目的。

CountDownLatch实践

司机和工人,工人必须等到司机来了才能装货上车,司机必须得等到所有工人把货物装上车了之后才能把车开走。

同步类代码:

 1 import java.util.concurrent.CountDownLatch;
 2 
 3 public class Worker implements Runnable {
 4  
 5     private String workerCode;
 6  
 7     private CountDownLatch startLatch;
 8     private CountDownLatch latch;
 9  
10     Worker(CountDownLatch startLatch, CountDownLatch latch, String workerCode) {
11         this.startLatch = startLatch;
12         this.latch = latch;
13         this.workerCode = workerCode;
14     }
15  
16     public void run() {
17         try {
18             startLatch.await();
19             doWork();
20             latch.countDown();
21         } catch (InterruptedException e) {
22             e.printStackTrace();
23         }
24     }
25  
26     private void doWork() {
27         System.out.println("Worker " + workerCode + " is loading goods...");
28     }
29 }
工人类
 1 import java.util.concurrent.CountDownLatch;
 2 import java.util.concurrent.ExecutorService;
 3 import java.util.concurrent.Executors;
 4 
 5 public class Driver {
 6     public static void main(String[] args) throws InterruptedException {
 7         CountDownLatch startLatch = new CountDownLatch(1);
 8         CountDownLatch latch = new CountDownLatch(10);
 9         ExecutorService executor = Executors.newFixedThreadPool(10);
10  
11         for(int i=0; i<10; i++) {
12             executor.execute(new Worker(startLatch, latch, "worker" + i));
13         }
14  
15         System.out.println("Driver is here.");
16  
17         startLatch.countDown();
18  
19         System.out.println("Workers get to work.");
20  
21         latch.await();
22  
23         System.out.println("Driver is ready to go.");
24  
25         executor.shutdown();
26     }
27 }
司机类

 

方法3:通过java.util.concurrent.Executors中的方法创建一个线程池,用这个线程池来启动线程。启动所有要启动的线程后,执行线程池的shutdown()方法,即在所有线程执行完毕后关闭线程池。然后通过线程池的isTerminated()方法,判断线程池是否已经关闭。线程池成功关闭,就意味着所有线程已经运行完毕了。

线程池方法示例代码:

 1 import java.util.concurrent.ExecutorService;  
 2 import java.util.concurrent.Executors;  
 3 
 4 public class Test {  
 5   
 6     public static void main(String args[]) throws InterruptedException {  
 7         ExecutorService exe = Executors.newFixedThreadPool(50);  
 8         for (int i = 1; i <= 5; i++) {  
 9             exe.execute(new SubThread(i));  
10         }  
11         exe.shutdown();  
12         while (true) {  
13             if (exe.isTerminated()) {  
14                 System.out.println("结束了!");  
15                 break;  
16             }  
17             Thread.sleep(200);  
18         }  
19     }  
20 }
View Code

 

一个思路:

给所有的线程加上同步(同一个锁),主线程在启动其他所有线程后wait()。每个线程运行结束后,执行notify()方法。设定一个值为其他线程数量的int计数器count,写一个while循环,循环条件为count-->0,循环内容为wait()。则所有线程运行结束后正好while循环结束。

致命缺陷:如果几个线程同时运行结束,有可能在主线程还没运行时,已经执行了好几次notify()方法。如果这样的话,while循环就永远不会结束了,主线程一直wait()下去。
posted @ 2018-09-12 16:13  carsonwuu  阅读(4432)  评论(0编辑  收藏  举报