Thread.join()详解

     Thread.jion()是干嘛用的,网上看到一个网友举的例子非常有意思。你准备洗澡,需要准备的步骤,准备好衣服,沐浴的东西及烧水这些事情,由于烧水耗时太长,如果也放在主线程之中,就很浪费资源,所以如果我们另开线程去处理,就会达到很好效果,于是乎在准备好衣服,沐浴的东西之前就去开子线程烧水,烧水的过程中主线程准备好衣服,沐浴的东西,此时就等待水烧好,然后方可痛快的洗澡了!!  

下面我们来实现一下这个过程。

public class Bathe {
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		HeatingWater heatingWater = new HeatingWater();//新建一个烧水进程
		Bathemain bathmain = new Bathemain(heatingWater);//创建一个洗澡进程
		
		bathmain.start();
		heatingWater.start();
	}
}
//创建一个洗澡的主线程
class Bathemain extends Thread{
    private HeatingWater heatingWater;
    public Bathemain(HeatingWater heatingWater){
    	this.heatingWater = heatingWater;
    }
	@Override
	public void run() {
		// TODO Auto-generated method stub
		System.out.println("准备开始洗澡了");
		System.out.println("准备换洗衣服");
		System.out.println("准备沐浴的东西");
		try {
			heatingWater.join();
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		System.out.println("洗澡了");
	}}
//烧水的线程,因为是热水器在做不需要你,可和其他准备同步执行
class HeatingWater extends Thread{

	@Override
	public void run() {
		// TODO Auto-generated method stub
		System.out.println("正在烧水...");
		try {
			Thread.sleep(3000);//烧水时间比较长
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}}

        准备洗澡工作和烧水同时开始,但开始洗澡前烧水的线程一定要执行结束,水烧开了才可以向下执行。当主线程执行到Thead1.join()的时候,看Thread1是否执行结束,如果结束向下执行,否则一直等待,直到调用Thread1执行结束或被打断。

此外还有两个带参数的方法:

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

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

比如你有急事,等不及水烧开就要洗澡,可以给join()方法设置一个值,比如改成 heatingWater.join(1500); 当等够1.5秒,水虽没烧开,但不等了,继续向下执行。

JDK源码:

public final synchronized void join(long millis)
    throws InterruptedException {
        long base = System.currentTimeMillis();
        long now = 0;

        if (millis < 0) {
            throw new IllegalArgumentException("timeout value is negative");
        }

        if (millis == 0) {
            while (isAlive()) {
                wait(0);
            }
        } else {
            while (isAlive()) {
                long delay = millis - now;
                if (delay <= 0) {
                    break;
                }
                wait(delay);
                now = System.currentTimeMillis() - base;
            }
        }
    }
       isAlive()判断Thread.join()的Thread线程是否在执行,如果在执行则调用wait()方法,如果还未开始执行或已执行结束,isAlive()返回false,不执行wait()。





你可能感兴趣的:(java)