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\n",new Date());
	    try {
	      TimeUnit.SECONDS.sleep(4);
	    } catch (InterruptedException e) {
	      e.printStackTrace();
	    }
	    System.out.printf("Data sources loading has finished: %s\n",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\n",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\n",new Date());
	    try {
	      TimeUnit.SECONDS.sleep(4);
	    } catch (InterruptedException e) {
	      e.printStackTrace();
	    }
	    System.out.printf("Data sources loading has finished: %s\n",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\n",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\n",new Date());
	    try {
	      TimeUnit.SECONDS.sleep(4);
	    } catch (InterruptedException e) {
	      e.printStackTrace();
	    }
	    System.out.printf("Data sources loading has finished: %s\n",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\n",new Date());
	    try {
	      TimeUnit.SECONDS.sleep(6);
	    } catch (InterruptedException e) {
	      e.printStackTrace();
	    }
	    System.out.printf("Network connect loading has finished: %s\n",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\n",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》

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

时间: 2024-09-27 16:27:27

Thread.join()分析方法的相关文章

C#多线程Thread.Join()的详解

class TestThread { private static void FirstThreadFun() { for (int i = 0; i < 10; i++) { Console.WriteLine(Thread.CurrentThread.Name + " i = " + i); } Console.WriteLine(Thread.CurrentThread.Name + " 执行完毕"); } static void Main(string

java中synchronize锁 volatile thread.join()方法的使用

对于并发工作,你永远不知道一个线程何时运行,你需要某种方式来避免两个任务访问相同的资源,即要避免资源竞争,至少在关键代码上不能出现这样的情况,否则多个线程同时对某个内存区域操作会导致数据破坏. 程序代码中的临界区是需要互斥访问的,同一时刻只能有一个线程来访问临界区,也就是线程对临界区的访问时互斥的. 竞争条件:当多个线程同时访问某个共享的内存区域并且对其进行读写操作时,就会出现数据破坏.这就是竞争条件.避免竞争条件的方法是synchronized加锁. 样例,设有一个现成,该线程的任务是对共享变

Thread.join()方法解析

API: join public final void join() throws InterruptedException 等待该线程终止. 抛出: InterruptedException - 如果任何线程中断了当前线程.当抛出该异常时,当前线程的中断状态 被清除. join public final void join(long millis) throws InterruptedException 等待该线程终止的时间最长为 millis 毫秒.超时为 0 意味着要一直等下去. 参数:

性能分析之-- JAVA Thread Dump 分析综述

性能分析之-- JAVA Thread Dump 分析综述 一.Thread Dump介绍 1.1什么是Thread Dump? Thread Dump是非常有用的诊断Java应用问题的工具.每一个Java虚拟机都有及时生成所有线程在某一点状态的thread-dump的能力,虽然各个 Java虚拟机打印的thread dump略有不同,但是大多都提供了当前活动线程的快照,及JVM中所有Java线程的堆栈跟踪信息,堆栈信息一般包含完整的类名及所执行的方法,如果可能的话还有源代码的行数. 1.2 T

java多线程同步以及线程间通信详解&amp;消费者生产者模式&amp;死锁&amp;Thread.join()(多线程编程之二)

本篇我们将讨论以下知识点: 1.线程同步问题的产生 什么是线程同步问题,我们先来看一段卖票系统的代码,然后再分析这个问题: [java] view plain copy print? package com.zejian.test; /** * @author zejian * @time 2016年3月12日 下午2:55:42 * @decrition 模拟卖票线程 */ public class Ticket implements Runnable { //当前拥有的票数 private 

Android APP性能分析方法及工具

近期读到<Speed up your app>一文.这是一篇关于Android APP性能分析.优化的文章.在这篇文章中,作者介绍他的APP分析优化规则.使用的工具和方法.我觉得值得大家借鉴.英文好的读者可读原文(链接:http://blog.udinic.com/2015/09/15/speed-up-your-app). 1.作者的规则 作者每次着手处理或寻找性能问题时,遵循下列规则: 时常检测 在更新APP前后,用测试工具软件多检测几次APP性能,可快速得到测试数据.这些数字是不会说谎的

颠覆我的Thread.join()

学而时习之,不亦说乎!                              --<论语> 为什么说是颠覆? 1)任何对象都可以作为锁对象,锁对象的行为都是一样的吗?之前我一直认为锁对象的方法都是定义在Object类中,而所有类都是Object的子类,这些方法又都是native方法,那么用哪个对象作为锁对象又有什么区别呢? 2)一个线程对象a在run()方法内部调用线程对象b的join()方法,那么是将b线程加入,等到b线程执行完毕再执行a线程?那么如果还有一个正在执行的c线程呢,线程c也

性能分析之-- JAVA Thread Dump 分析综述【转】

一.Thread Dump介绍 1.1什么是Thread Dump? Thread Dump是非常有用的诊断Java应用问题的工具.每一个Java虚拟机都有及时生成所有线程在某一点状态的thread-dump的能力,虽然各个 Java虚拟机打印的thread dump略有不同,但是大多都提供了当前活动线程的快照,及JVM中所有Java线程的堆栈跟踪信息,堆栈信息一般包含完整的类名及所执行的方法,如果可能的话还有源代码的行数. 1.2 Thread Dump特点 1. 能在各种操作系统下使用 2.

Java Thread.join的作用和原理

很多人对Thread.join的作用以及实现了解得很少,毕竟这个api我们很少使用.这篇文章仍然会结合使用及原理进行深度分析 内容导航 Thread.join的作用 Thread.join的实现原理 什么时候会使用Thread.join Thread.join的作用 之前有人问过我一个这样的面试题 Java中如何让多线程按照自己指定的顺序执行? 这个问题最简单的回答是通过Thread.join来实现,久而久之就让很多人误以为Thread.join是用来保证线程的顺序性的. 下面这段代码演示了Th