首页 > 编程语言 > 详细

Java多线程之join

时间:2015-12-18 02:12:33      阅读:439      评论:0      收藏:0      [点我收藏+]

? ? join是线程的一个方法,在API中,它的英文解释是Waits for this thread to die.等待此线程死亡。谁等待此线程死亡呢?不难看出,这过程中至少存在两个线程,一个调用线程的线程,一个被调用的线程。我们通过一个简单的示例来理解这句话。? ??

package com.doufu.thread.t01;

class ThreadA extends Thread{

	private String name;
	
	public ThreadA(String name){
		this.name = name;
	}
	
	@Override
	public void run() {
		try {
			Thread.sleep(1000);//让此线程等待1秒
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println(name);
	}
	
}
public class JoinTest01 {
	public static void main(String[] args) throws InterruptedException {
		ThreadA t = new ThreadA("T1");
		t.start();
		t.join();
		System.out.println("main");
	}
}

? ? ?在上面代码中,调用线程的线程是main即主线程,被调用的线程是t。t.join()的意思即等待t的死亡(运行结束),等待t运行结束的线程就是main。所以上面的代码执行结果应该是先打印T1,再打印main。? ??

bubuko.com,布布扣

? ? 通过以上代码,可以理解,在A线程中调用另外一个线程B的join方法,即让线程A进入Block状态,直到线程B运行结束。下面再看一个示例:

? ? ?只贴出了修改的部分

public class JoinTest01 {
	public static void main(String[] args) throws InterruptedException {
		ThreadA t = new ThreadA("T1");
		t.join();
		t.start();
		System.out.println("main");
	}
}

? ?运行结果:

?

? ??
bubuko.com,布布扣

? 看这输出结果,是不是觉得不对,不是好说了,在main中调用t的join方法,会让main先挂起,直到t执行结束吗,怎么先打印main了呢?我们来看下Thread类的join源码:

? ??

public final void join() throws InterruptedException {
        join(0);
    }

? ? join(),实际上是调用另外一个join(long millis)的方法,我们再来看下join(long millis)方法? ?

?

?

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;
            }
        }
    }

? ?从源码中看出,如果调用join()方法时,线程不是活着的,则无效。以下是isAlive()的源码,注意看下方法注释??

?

?

/**
     * Tests if this thread is alive. A thread is alive if it has
     * been started and has not yet died.
     *
     * @return  <code>true</code> if this thread is alive;
     *          <code>false</code> otherwise.
     */
    public final native boolean isAlive();

? ?我们来看一个面试题:? ? ?

写道
现在有T1、T2、T3三个线程,你怎样保证T2在T1执行完后执行,T3在T2执行完后执行?

? ? 此面试题,我们可以用join来实现? ?

class ThreadA extends Thread{

	private String name;
	
	public ThreadA(String name){
		this.name = name;
	}
	
	@Override
	public void run() {
		try {
			Thread.sleep(1000);//让此线程等待1秒
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println(name);
	}
	
}

class ThreadB extends Thread{

	private String name;
	private Thread thread;
	public ThreadB(String name,Thread thread){
		this.name = name;
		this.thread = thread;
	}
	
	@Override
	public void run() {
		try {
			thread.join();//让此线程进入Block
			Thread.sleep(1000);//让此线程等待1秒
		} catch (InterruptedException e1) {
			e1.printStackTrace();
		}
		System.out.println(name);
	}
}
public class JoinTest01 {
	public static void main(String[] args) throws InterruptedException {
		ThreadA t1 = new ThreadA("T1");
		ThreadB t2 = new ThreadB("T2",t1);
		ThreadB t3 = new ThreadB("T3",t2);
		
		t1.start();
		t2.start();
		t3.start();
	}
}

?运行结果:? ?

bubuko.com,布布扣
?

?

?

Java多线程之join

原文:http://h140465.iteye.com/blog/2264768

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!