public class TestJoin 

public static void main(String [] args) 

ThreadA a=new ThreadA(); 
ThreadB b=new ThreadB(a); 
//b.setPriority(10); 
b.start(); 
a.start(); } } 
class ThreadB extends Thread 

ThreadA a; 
public ThreadB(ThreadA a) 

this.a = a; 
} public void run() 

System.out.println("Thread B has started!"); 
try 

a.join(); 

catch(InterruptedException e) 
{e.printStackTrace();} 
System.out.println("Thread B is ended!"); 


class ThreadA extends Thread 

public void run() 

System.out.println("Thread A has started!"); 
try{ sleep(300); 
}catch(InterruptedException e){ 
e.printStackTrace(); 

System.out.println("Thread A ends!"); 

} //将main()方法中注释的代码去掉后再运行一次,出来的结果完全不同,为什么? 
//我这个是在windows下运行的,跪求答案

解决方案 »

  1.   

    在我这里注销掉b.setPriority(10);
    运行结果:
    Thread B has started!
    Thread A has started!
    Thread A ends!
    Thread B is ended!如果main方法里加入b.setPriority(10);这句,
    运行结果:
    Thread B has started!
    Thread A has started!
    Thread A ends!
    Thread B is ended!在我的电脑里结果是一样的。我觉得LZ既然想测试Thread的join方法,
    我就说说这个join方法好了。首先,ThreadB启动后,执行它的run方法,
    则输入Thread B has started!,
    然后就执行a.join();,
    这个a就是main方法里启动的线程ThreadA的对象,
    这句话的意思就是,在a.join后面的语句,只有等到线程a返回了(也就是a.isAlive()返回false的时候),才能被执行。所以,执行到 a.join()的时候,阻塞了。
    这时候线程ThreadA开始启动,执行,
    输出了
    Thread A has started!
    Thread A ends!
    ThreadA 的run方法返回后,ThreadB在被阻塞的地方继续执行,所以后面输出了
    Thread B is ended!
    关于这个join的用法,可以参考下源码。其实还蛮好理解的。
    当你调用到a.join()的时候,
    源码这样调用的,
    在Thread类里:    public final void join() throws InterruptedException {
    join(0);//参数是0
        }
    然后在Thread类里,进入 join(0)方法:    public final synchronized void join(long millis) //这个方法由我们调用时,参数millis为0
        throws InterruptedException {
    long base = System.currentTimeMillis();
    long now = 0; if (millis < 0) {
                throw new IllegalArgumentException("timeout value is negative");
    } if (millis == 0) {//因为millis 为0,所以符合这个判断语句
        while (isAlive()) {//判断此线程是否为Alive的状态。这里的此线程就是调用者----a
    wait(0);//如果isAlive()返回true,阻塞。直到isAlive()返回false了,才能向下继续执行。
        }
    } else {
        while (isAlive()) {
    long delay = millis - now;
    if (delay <= 0) {
        break;
    }
    wait(delay);
    now = System.currentTimeMillis() - base;
        }
    }
        }
      

  2.   

    代码有问题, 你在 a.join();  之前加上一句sleep(100) 用来保证 a 线程已经启动了. 这样就会得到你想要的结果.你现在的代码中,执行到 a.join();  这句时,a 线程有可能还没有启动,那么就不会进入等待状态了.
      

  3.   

    最后,楼主把代码里的main方法改一下:
    public static void main(String[] args) throws InterruptedException {
    ThreadA a = new ThreadA();
    ThreadB b = new ThreadB(a);
    // b.setPriority(10);
    b.start();

    Thread.sleep(1000);//加上这句,这句就是确保在线程b启动之后,执行了a.join()后,线程a还没有启动呢。
    //这时候的打印结果就是把线程ThreadB的输出信息都输出了,才会输出ThreadA的。

    a.start();
    }
    之所以在我的电脑上b.setPriority(10);这句加与不加的时候,运行结果一样,
    这跟电脑的环境有关。但加上Thread.sleep(1000);的话,应该可以满足你的要求,见我1楼的帖子,看着源码,
    应该能理解,isAlive()此时就返回false了。
    所以得以继续向下执行。
      

  4.   

    本帖最后由 java2000_net 于 2009-02-11 09:30:14 编辑
      

  5.   

    join等待的是已经运行中的活动的线程,如果本身还没有运行,根本就不会等待,上面的源码已经很清楚了.isAlive(),如果a还没有start的话b根本就不会等待.
      

  6.   

    呵呵~~谢谢,你讲的意思 我明白了...但我没搞清楚线程的中断问题,也就是
    isAlive()方法和isInterrupted()这2个方法的区别.然后还有,interrupt()这个方法是中断线程,那线程是处于什么状态呢?
    isAlive()方法是用来判断什么的?
      

  7.   

    join等待的是已经运行中的活动的线程,如果本身还没有运行,根本就不会等待,上面的源码已经很清楚了.isAlive(),如果a还没有start的话b根本就不会等待.
    领会了