多线程编程之join()方法(含源码)

来源:互联网 发布:差分和微分的区别 知乎 编辑:程序博客网 时间:2024/05/20 14:40

join()方法:

在主线程创建并启动子线程,如果子线程需要太长时间,主线程会提前结束,等子线程完成run方法后,子线程结束。
但是有时候我们需要等待子线程完成后再执行主线程。例如:子线程处理一个数据,主线程需要取得这个数据,就需要使用join方法了。

package join;public class MyThread extends Thread{    public void run() {        try {            int secondValue=(int) (Math.random()*10000);            System.out.println(secondValue);            Thread.sleep(secondValue);        }catch(InterruptedException e) {            e.printStackTrace();        }    }}package join;public class Test {    public static void main(String[] args) {        try {            MyThread mythread=new MyThread();            mythread.start();            mythread.join();            System.out.println("mythread执行完输出☆☆☆☆☆");        }catch(InterruptedException e) {            e.printStackTrace();        }    }}控制台输出:9808mythread执行完输出☆☆☆☆☆

以上就是join的使用。
从join方法的特性我们了解到,join具有使得线程排队的效果,就像同步一样。但是join方法底层使用的是wait方法。
下面我们来看看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(long millis)方法的参数是0时,运行这个方法的线程就会执行wait(0)。我们再看看wait的源码:

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

其实wait()方法其实执行的就是wait(0)。所以主线程一直等待。那么主线程是怎么被唤醒的呢?
我们看join(long milis)源码可以知道,这个方法使用synchronized修饰符的,也就是调用这个方法需要获得子线程对象的锁,然后调用wait,即先获得锁后释放锁,然后等待唤醒。
After run() finishes, notify() is called by the Thread subsystem.
当线程运行结束的时候,notify是被线程的子系统调用的

分别以普通对象和线程对象作为锁,当使用线程对象作为所得时候,如果锁对象执行完毕了。wait就会停止等待继续执行

public class ThreadTestl {    public static void main(String[] args) {        final MyLockThread mylockthread = new MyLockThread();        //final Object mylockthread = new Object();        new Thread(new Runnable() {            @Override            public void run() {                synchronized (mylockthread) {                    System.err.println(1);                    try {                        mylockthread.wait(0);                    } catch (InterruptedException e) {                        e.printStackTrace();                    }                    System.err.println(2);                }            }        }).start();        mylockthread.start();    }    static class MyLockThread extends Thread {        public MyLockThread() {        }        @Override        public void run() {            System.err.println("MyLockThread");        }    }}

所以到现在我们知道了join的工作原理了。

阅读全文
1 0