zoukankan      html  css  js  c++  java
  • Thread.join()分析方法

    API:

    join

    public final void join()
                    throws InterruptedException
    等待该线程终止。


    抛出:
    InterruptedException - 假设不论什么线程中断了当前线程。当抛出该异常时,当前线程的中断状态 被清除。

    join

    public final void join(long millis)
                    throws InterruptedException
    等待该线程终止的时间最长为 millis 毫秒。超时为 0 意味着要一直等下去。


    參数:
    millis - 以毫秒为单位的等待时间。
    抛出:
    InterruptedException - 假设不论什么线程中断了当前线程。

    当抛出该异常时,当前线程的中断状态 被清除。

    join

    public final void join(long millis,
                           int nanos)
                    throws InterruptedException
    等待该线程终止的时间最长为 millis 毫秒 + nanos 纳秒。


    參数:
    millis - 以毫秒为单位的等待时间。

    nanos - 要等待的 0-999999 附加纳秒。

    抛出:
    IllegalArgumentException - 假设 millis 值为负,则 nanos 的值不在 0-999999 范围内。
    InterruptedException - 假设不论什么线程中断了当前线程。

    当抛出该异常时。当前线程的中断状态 被清除。

    解析

    Thread.join()。是用来指定当前主线程等待其它线程运行完成后。再来继续运行Thread.join()后面的代码


    例1:

    package com.example;
    
    import java.util.Date;
    import java.util.concurrent.TimeUnit;
    
    public class DataSourcesLoader implements Runnable{
    
    	@Override
    	public void run() {
    		System.out.printf("Beginning data sources loading: %s
    ",new Date());
    	    try {
    	      TimeUnit.SECONDS.sleep(4);
    	    } catch (InterruptedException e) {
    	      e.printStackTrace();
    	    }
    	    System.out.printf("Data sources loading has finished: %s
    ",new Date());
    	}
    
    	public static void main(String[] args){
    		DataSourcesLoader dsLoader = new DataSourcesLoader();
    	    Thread thread1 = new Thread(dsLoader,"DataSourceThread");
    	    
    	    thread1.start();
    	    
    	    try {
    	        thread1.join();
    	      } catch (InterruptedException e) {
    	        e.printStackTrace();
    	      }
    	      
    	      System.out.printf("Main: Configuration has been loaded: %s
    ",new Date());
    	}
    
    }
    
    运行结果:

    Beginning data sources loading: Fri Nov 14 14:27:31 CST 2014
    Data sources loading has finished: Fri Nov 14 14:27:35 CST 2014
    Main: Configuration has been loaded: Fri Nov 14 14:27:35 CST 2014
    假设去掉thread1.join(),运行的结果例如以下:

    Main: Configuration has been loaded: Fri Nov 14 14:28:33 CST 2014
    Beginning data sources loading: Fri Nov 14 14:28:33 CST 2014
    Data sources loading has finished: Fri Nov 14 14:28:37 CST 2014
    通过结果。就能够非常明显的说明上面红字的部分:“再来继续运行Thread.join()后面的代码

    例2:

    package com.example;
    
    import java.util.Date;
    import java.util.concurrent.TimeUnit;
    
    public class DataSourcesLoader implements Runnable{
    
    	@Override
    	public void run() {
    		System.out.printf("Beginning data sources loading: %s
    ",new Date());
    	    try {
    	      TimeUnit.SECONDS.sleep(4);
    	    } catch (InterruptedException e) {
    	      e.printStackTrace();
    	    }
    	    System.out.printf("Data sources loading has finished: %s
    ",new Date());
    	}
    
    	public static void main(String[] args){
    		DataSourcesLoader dsLoader = new DataSourcesLoader();
    	    Thread thread1 = new Thread(dsLoader,"DataSourceThread");
    	    
    	    thread1.start();
    	    
    	    try {
    	        thread1.join(3000);
    	      } catch (InterruptedException e) {
    	        e.printStackTrace();
    	      }
    	      
    	      System.out.printf("Main: Configuration has been loaded: %s
    ",new Date());
    	}
    
    }
    

    这里使用的是:
    thread1.join(3000);
    这句话的意思是,仅仅要满足以下2个条件中的一个时,主线程就会继续运行thread.join()后面的代码:

    条件1:thread1 运行完成。

    条件2:已经等待 thread1 运行了3000ms.

    样例中。thread1 自身的运行时间是4s。而设置的等待时间是3s,所以得到的运行结果例如以下。thread1还没有运行完,主线程就開始运行后面的代码。由于 thread1 等待的时间已经超时了:

    Beginning data sources loading: Fri Nov 14 14:35:45 CST 2014
    Main: Configuration has been loaded: Fri Nov 14 14:35:48 CST 2014
    Data sources loading has finished: Fri Nov 14 14:35:49 CST 2014
    



    那么结合上面的2个样例。我们能够判断出以下代码的运行结果了:

    例3:

    package com.example;
    
    import java.util.Date;
    import java.util.concurrent.TimeUnit;
    
    public class DataSourcesLoader implements Runnable{
    
    	@Override
    	public void run() {
    		System.out.printf("Beginning data sources loading: %s
    ",new Date());
    	    try {
    	      TimeUnit.SECONDS.sleep(4);
    	    } catch (InterruptedException e) {
    	      e.printStackTrace();
    	    }
    	    System.out.printf("Data sources loading has finished: %s
    ",new Date());
    	}
    
    }

    package com.example;
    
    import java.util.Date;
    import java.util.concurrent.TimeUnit;
    
    public class NetworkConnectionsLoader implements Runnable{
    
    	@Override
    	public void run() {
    		System.out.printf("Beginning network connect loading: %s
    ",new Date());
    	    try {
    	      TimeUnit.SECONDS.sleep(6);
    	    } catch (InterruptedException e) {
    	      e.printStackTrace();
    	    }
    	    System.out.printf("Network connect loading has finished: %s
    ",new Date());
    		
    	}
    	
    	public static void main(String[] args){
    		DataSourcesLoader dsLoader = new DataSourcesLoader();
    	    Thread thread1 = new Thread(dsLoader,"DataSourceThread");
    	    
    	    NetworkConnectionsLoader ncLoader = new NetworkConnectionsLoader();
    	    Thread thread2 = new Thread(ncLoader,"NetworkConnectionLoader");
    	    
    	    thread1.start();
    	    thread2.start(); 
    	    
    	    try {
    	        thread1.join();
    	        thread2.join(1900);
    	      } catch (InterruptedException e) {
    	        e.printStackTrace();
    	      }
    	      
    	      System.out.printf("Main: Configuration has been loaded: %s
    ",new Date());
    	}
    
    }
    
    运行结果:

    Beginning data sources loading: Fri Nov 14 14:39:20 CST 2014
    Beginning network connect loading: Fri Nov 14 14:39:20 CST 2014
    Data sources loading has finished: Fri Nov 14 14:39:24 CST 2014
    Main: Configuration has been loaded: Fri Nov 14 14:39:26 CST 2014
    Network connect loading has finished: Fri Nov 14 14:39:26 CST 2014
    

    注意:假设把例3的 thread2.join(1900) 部分改动为:

    thread2.join(3000);
    结果会和上面的一样吗?

    依据我最開始指出的“Thread.join()。是用来指定当前主线程等待其它线程运行完成后,再来继续运行Thread.join()后面的代码

    我们能够看到,运行结果会有区别:

    Beginning data sources loading: Fri Nov 14 14:41:21 CST 2014
    Beginning network connect loading: Fri Nov 14 14:41:21 CST 2014
    Data sources loading has finished: Fri Nov 14 14:41:25 CST 2014
    Network connect loading has finished: Fri Nov 14 14:41:27 CST 2014
    Main: Configuration has been loaded: Fri Nov 14 14:41:27 CST 2014</span>
    

    至于为什么会有这个区别,我上面也已经说明了,我想这个应该不难理解。

    PS:代码部分截取来自《Java 7 Concurrency Cookbook》

    版权声明:本文博客原创文章。博客,未经同意,不得转载。

  • 相关阅读:
    VGG卷积神经网络模型解析
    利用Azure内容审查器审查违规内容(上)
    Kotlin + 协程 + Retrofit + MVVM优雅的实现网络请求
    OpenCV 实现图片的水平投影与垂直投影,并进行行分割
    C#自定义ip控件
    C#、Java中的一些小知识点总结(持续更新......)
    WinForm程序,实现只启动一个实例
    将DLL文件直接封装进exe执行文件中(C#)
    WinForm下的loading框的实现
    获取串口映射的COM端口号
  • 原文地址:https://www.cnblogs.com/lcchuguo/p/4710057.html
Copyright © 2011-2022 走看看