join方法源码如下:
 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);
        //不明这里,如果是0的话,调用此方法的线程会一直等待下去,以 t.join()这种
        //形式调用,调用此方法的线程是如何唤醒的呢
    }
} else {
    while (isAlive()) {
long delay = millis - now;
if (delay <= 0) {
    break;
}
wait(delay);
now = System.currentTimeMillis() - base;
    }
}
    }
测试代码:class T extends Thread{
public void run(){
try{
Thread.currentThread().sleep(2000);
System.out.println("run!!!");
}catch(Exception e){}

}public static void main(String[] s)throws Exception{
T t=new T();
System.out.println("begin!");
t.start();
t.join();
System.out.println("end!");
}
}

解决方案 »

  1.   

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

  2.   

    因为threadStatus这个值都是由本地方法来更新的,所以猜测join里的wait是由本地方法更新线程状态时唤醒的。
    我以前一直以为这是个自旋等待,因为我以为wait(0)会马上醒来
      

  3.   

    public final void wait(long timeout)
                    throws InterruptedException
    如果 timeout 为零,则不考虑实际时间,该线程将一直等待,直到获得通知。 public final void join(long millis)
                    throws InterruptedException
    等待该线程终止的时间最长为 millis 毫秒。超时为 0 意味着要一直等下去。设置为0就是要保证这个线程一定要执行完啊,0的时候还唤醒什么?要唤醒的话就设置为大于0
      

  4.   

    看一下代码:/**
     * 
     * @author bzwm
     * 
     */
    class CustomThread1 extends Thread {
    public CustomThread1() {
    super("[CustomThread1] Thread");
    }; public void run() {
    String threadName = Thread.currentThread().getName();
    System.out.println(threadName + " start.");
    try {
    for (int i = 0; i < 5; i++) {
    System.out.println(threadName + " loop at " + i);
    Thread.sleep(1000);
    }
    System.out.println(threadName + " end.");
    } catch (Exception e) {
    System.out.println("Exception from " + threadName + ".run");
    }
    }
    }public class JoinTestDemo { private static int i = 0; private static boolean isAlive(Thread a) {
    System.out.println("judge...." + i++);
    return a.isAlive(); } public static void main(String args[]) throws Exception {
    CustomThread1 a = new CustomThread1();
    a.start();
    Thread.sleep(100);
    synchronized (a) {
    System.out.println("CustomThread1 is alive or not??????");
    while (isAlive(a)) {
    System.out.println("CustomThread1 is alive.");
    a.wait(0);
    }
    }
    System.out.println("Done!");
    }
    }打印结果:
    [CustomThread1] Thread start.
    [CustomThread1] Thread loop at 0
    CustomThread1 is alive or not??????
    judge....0
    CustomThread1 is alive.
    [CustomThread1] Thread loop at 1
    [CustomThread1] Thread loop at 2
    [CustomThread1] Thread loop at 3
    [CustomThread1] Thread loop at 4
    [CustomThread1] Thread end.
    judge....1
    Done!在执行了a.wait(0);后,主线程就被阻塞了。当a线程返回后,程序继续运行,所以进行了第二次判断,
    由于此时调用isAlive方法返回false,所以就不再阻塞了。在这里,确实没有看到调用 a.notify()的方法。再来看看jdk中对于wait方法的解释:     * <li>The specified amount of real time has elapsed, more or less.  If 
         * <tt>timeout</tt> is zero, however, then real time is not taken into 
         * consideration and the thread simply waits until notified. 从这里分析,
    想弄清楚这个问题,得看看关于JVM的东西了。
      

  5.   

    二楼的弟兄猜是对的。只要是
    while(condition){
       wait();
    }
    other stmt;
    这样的程序以,其唤醒一定是条件不满足时notify,否则就是设计错误。
    换句话说,线程在wait什么?当然是wait noify动作。不过这只是表面上的,线程真正wait的是!condition,
    也就是能执行other stmt;的条件。所以一但达到这样的条件,就一定会notify,通知在这个对象上wait的线程。
    也就是改变状态的线程在条件不满足wait的时候一定会通知等待中的线程。为什么不是if(condition){
       wait();
    }而是
    while(condition){
       wait();
    }这不是自旋,而是为了多线程安全性。
    比如两个线程A,B执行到wait:if(listA.size() <= 0){
       wait();
    }
    listA.removeFirst();
    当线程C向listA中add一个元素并用notifyAll通知了wait的线程后,
    假如线程A抢到锁并运行listA.removeFirst();然后切换到B,因为B已经从wait
    中出来,所以肯定执行listA.removeFirst();而实际上这时listA.size() <= 0了。
    所以如果用while的话,无论A还是B即使刚从wait中出来也会再一次检查条件。不会在
    listA.size() <= 0时执行wait下面的的语句。