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 sleep
joinFinish
End 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 sleep
End sleep
joinFinish

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

public class JoinDemo{   

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

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

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

时间: 2024-10-13 05:12:42

8.Thread的join方法的相关文章

浅析Thread的join() 方法

Thread中的 join() 方法在实际开发过程中可能用的不是很多,但是在面试中作为考察基本功知识的扎实与否,经常会被用到.因此,对于 Thread 的 join() 方法进行了一定的研究. 常见的一种情景是如何保证创建多个线程保证其按照指定的顺序执行,最简单的一种方法是采用Thread.join() 方法来实现.以下是写的创建若干个线程的示例代码,通过采用创建一个实体类,重写其里面的run 方法来实现.如果指定少数的线程数,可以直接采用 thread.join()来实现,其原理是一致的. 1

Thread线程join方法自我理解

thread.join():等待thread线程运行终止,指的是main-thread(main线程)必须等待thread线程运行结束,才能继续thread.join();后面的代码 thread.join(long time):线程thread等待time时间之后,main-thread可以执行,注意time时间后,线程thread没有执行完,main-thread也可以运行 注意:上面2个方法必须在线程是alive的时候,才有这样的效果,否则不会有. join()方法源码是有调用wait()

C#中多线程Thread的Join方法

当我们的程序中使用多线程时,对资源的操作是需要特别留意的.如下面的例子:程序中有两个string对象(初始值为空),main函数中分别开启了两个线程去分别设置这两个string对象的值,然后在main函数中打印出这两个字符串的值.代码如下: static string str1 = string.Empty; static string str2 = string.Empty; static void Main(string[] args) { Thread worker1 = new Thre

java线程Thread的join方法。

1,方法的作用: 父线程等待子线程的执行. 如果是join或者join(0),即等待时长是0,父线程就会一直等到子线程执行结束, 如果是join(time),即等待时长是time数值,那父线程等待时长视情况而定: 第一种:子线程执行时长不需要time时长,那么父线程就可能不会等待到time时长,为什么是可能呢?是不是要考虑其他线程(不包括父线程,和子线程以外的线程),他也可能让父线程等待的(没有获取到cpu时间片等原因), 第二种:子线程执行时长超过time时长,那么父线程的等待时长,至少是ti

Thread中join()方法进行介绍

http://www.cnblogs.com/skywang12345/p/3479275.html https://blog.csdn.net/dabing69221/article/details/17472901 原文地址:https://www.cnblogs.com/yufeng218/p/9932721.html

Thread.Join() 方法

1. 什么是 the calling thread? 2. 什么是 a thread? 运行一个程序,即开启了一个进程和至少一个线程,干活的是线程而非进程!the calling thread 我们可以认为是MainThread(或者调用线程的线程,是不是有点绕?呵呵),a thread 我们就认为是被调用的线程. 最后,我们可以这样翻译MSDN:当 a thread 调用Join方法的时候,MainThread 就被停止执行,直到 a thread 线程执行完毕. 下面是测试代码: using

java--java.lang.Thread.join() 方法

Thread类join()方法重载了3次.分别是 join()throws InterruptedException; //无参数的join()等价于join(0),作用是一直等待该线程死亡 join(long millis, int nanos) throws InterruptedException;  //最多等待该线程死亡millis毫秒 join(long millis, int nanos) throws InterruptedException ; //最多等待该线程死亡milli

Java多线程中的join方法

新建一个Thread,代码如下: 1 package com.thread.test; 2 3 public class MyThread extends Thread { 4 private String name; 5 public MyThread(String name) { 6 this.name = name; 7 } 8 @Override 9 public void run() { 10 for (int i = 0; i < 100; i++) { 11 System.out.

Thread 的join

Context: threadObject:为Thread对象(以下带至) Thread的Join方法: 1.会暂停当前的线程,运行调用该方法的Thread对象所对应的线程将开始执行. 注意点: 1.Thread内部有个判断isAlive() 判断,注释是Tests if this thread is alive. A thread is alive if it has been started and has not yet died.也就是说没有threadObject.start(),th