zoukankan      html  css  js  c++  java
  • 【转载】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()下去。
  • 相关阅读:
    matlab中figure 创建图窗窗口
    matlab中imread 从图形文件读取图像
    matlab中imfinfo 有关图形文件的信息
    matlab中bitshift 将位移动指定位数
    matlab中reshape 重构数组
    matlab中find 查找非零元素的索引和值
    比特数
    matlab中fseek 移至文件中的指定位置
    poj 1039 Pipe(几何基础)
    poj 1556 The Doors(线段相交,最短路)
  • 原文地址:https://www.cnblogs.com/carsonwuu/p/9635451.html
Copyright © 2011-2022 走看看