首页 > 代码库 > 8.Thread的join方法

8.Thread的join方法

1.Thread类的join方法表示:当前线程执行结束再执行其它线程!在Thread类中有三个重载的方法分别是:

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

 

    public final synchronized void join(long millis, int nanos)    throws InterruptedException {        if (millis < 0) {            throw new IllegalArgumentException("timeout value is negative");        }        if (nanos < 0 || nanos > 999999) {            throw new IllegalArgumentException(                                "nanosecond timeout value out of range");        }        if (nanos >= 500000 || (nanos != 0 && millis == 0)) {            millis++;        }        join(millis);    }
    public final void join() throws InterruptedException {        join(0);    }

 如上就是Thread类的3个重载方法!

技术分享

大家注意一下:上面标记为红色的小红框的英文解释!以及无参的join方法,实际上调用的还是上面这个方法,如下源码所示:

技术分享

 

如下Demo演示:

public class JoinDemo{          public static int a = 0;      public static void main(String[] args) throws Exception {          Thread t = new Thread(){        	@Override            public void run() {                  for (int k = 0; k < 5; k++) {                      a = a + 1;                  }              }                    };          t.start();         System.out.println(a);      }         } 

  请 问程序的输出结果是5吗?答案是:有可能。其实你很难遇到输出5的时候,通常情况下都不是5。当然这也和机器有严重的关系。为什么呢?我的解释是当主线程 main方法执行System.out.println(a);这条语句时,线程还没有真正开始运行,或许正在为它分配资源准备运行。因为为线程分配资源需要时间,而main方法执行完t.start()方法后继续往下执行System.out.println(a);,这个时候得到的结果是a还没有被 改变的值0 。怎样才能让输出结果为5!其实很简单,join() 方法提供了这种功能。join() 方法,它能够使调用该方法的线程在此之前执行完毕。所以代码加入了join方法之后,代码如下所示:

public class JoinDemo{       public static int a = 0;      public static void main(String[] args) throws Exception {          Thread t = new Thread(){        	@Override            public void run() {                  for (int k = 0; k < 5; k++) {                      a = a + 1;                  }              }                    };          t.start();         t.join();//加入join方法        System.out.println(a);      }         }

为 了证明如果不使用t.join()方法,主线程main方法的System.out.println(a);语句将抢先执行,我们可以在main方法中加入一个循环,这个循环用来延长main方法执行的时间,循环次数将严重取决于机器性能。如果循环次数得当,我们也可以看到a的输出结果是5。

public class JoinDemo{       public static int a = 0;      public static void main(String[] args) throws Exception {          Thread t = new Thread(){        	@Override            public void run() {                  for (int k = 0; k < 5; k++) {                      a = a + 1;                      System.out.println("a的值:"+a);                }              }                    };          t.start();         for (int i=0; i<300; i++) {                            System.out.println(i);          }          System.out.println("静态变量的值为:"+a);      }         } 

 而使用了join方法之后,a的值就一直是5,但是这里需要注意的是:join方法是位于start方法之后的!

public class JoinDemo{       public static int a = 0;      public static void main(String[] args) throws Exception {          Thread t = new Thread(){        	@Override            public void run() {                  for (int k = 0; k < 5; k++) {                      a = a + 1;                      System.out.println("a的值:"+a);                }              }                    };          t.start();         //join方法位于start方法之后!        t.join();        for (int i=0; i<300; i++) {                            System.out.println(i);          }          System.out.println("静态变量的值为:"+a);      }         } 

 如下所示:

package com.bawei.multithread;public class JoinDemo{       public static int a = 0;      public static void main(String[] args) throws Exception {          Thread t = new Thread(new RunnableImpl());         t.start();         try {             t.join(100);             System.out.println("joinFinish");         } catch (InterruptedException e) {             e.printStackTrace();              }     }         } class RunnableImpl implements Runnable {      public void run() {          try {              System.out.println("Begin sleep");              Thread.sleep(500);             System.out.println("End sleep");          } catch (InterruptedException e) {              e.printStackTrace();          }        }  }  

 代码执行结果:

Begin sleepjoinFinishEnd sleep

 结果永远是这个,也就是说当我们为join方法指定了参数了的话,就表示main线程最多会等待这个t线程100毫秒,如果t线程100毫秒都还没执行完,那我也就不管了,我就去不等了,先去干我自己(main线程)的事了!

但是如果我们将t线程等待的时间该为1000,我们在运行如下代码:

package com.bawei.multithread;public class JoinDemo{       public static int a = 0;      public static void main(String[] args) throws Exception {          Thread t = new Thread(new RunnableImpl());         t.start();         try {             t.join(1000);             System.out.println("joinFinish");         } catch (InterruptedException e) {             e.printStackTrace();              }     }         } class RunnableImpl implements Runnable {      public void run() {          try {              System.out.println("Begin sleep");              Thread.sleep(500);             System.out.println("End sleep");          } catch (InterruptedException e) {              e.printStackTrace();          }        }  }  

 此时就会看到代码的运行结果如下所示:

Begin sleepEnd sleepjoinFinish

 如下给大家演示个好玩的东西:

public class JoinDemo{       public static void main(String[] args) throws Exception {        Thread.currentThread().join();    }         } 

 虽然上面就这简简单单的几行代码,但是这个代码就是不会停止,为什么呢?

这是因为main线程一运行,它就执行main方法中的代码:等待自己结束,但是自己有没有结束呢?没有,它也在干事情,就是:在等待自己结束,由于它永远等待不了自己结束,所以这个main线程也就永远不会退出,会一直运行下去!

 

8.Thread的join方法