美文网首页
线程阻塞(四),join及源码解析

线程阻塞(四),join及源码解析

作者: William_hi | 来源:发表于2018-05-18 15:51 被阅读0次

有一个笔试题,A、B、C三个线程,怎么保证A执行完后再执行B,B执行完后再执行C。

最简单的就是join 了吧。直接上代码:

public static void main(String[] args) throws InterruptedException {
        PrintThread threadA = new PrintThread("Thread A");
        PrintThread threadB = new PrintThread("Thread B");
        PrintThread threadC = new PrintThread("Thread C");
        threadA.start();
        threadA.join();
        threadB.start();
        threadB.join();
        threadC.start();
    }

    static class PrintThread extends Thread {
        PrintThread(String name) {
            super(name);
        }

        @Override
        public void run() {
            System.out.println(getName() + " start");
            try {
                sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(getName() + " end ...");
        }
    }

执行结果:

Thread A start
Thread A end ...
Thread B start
Thread B end ...
Thread C start
Thread C end ...

那么join是怎么实现的呢?看下源码:

  /**
     * Waits for this thread to die.
     *
     * <p> An invocation of this method behaves in exactly the same
     * way as the invocation
     *
     * <blockquote>
     * {@linkplain #join(long) join}{@code (0)}
     * </blockquote>
     *
     * @throws  InterruptedException
     *          if any thread has interrupted the current thread. The
     *          <i>interrupted status</i> of the current thread is
     *          cleared when this exception is thrown.
     */
    public final void join() throws InterruptedException {
        join(0);
    }

注意下注释:等待此线程执行完。

join()方法实际上调用了join(long millis),参数是0,再往下看:

    /**
     * Waits at most {@code millis} milliseconds for this thread to
     * die. A timeout of {@code 0} means to wait forever.
     *
     * <p> This implementation uses a loop of {@code this.wait} calls
     * conditioned on {@code this.isAlive}. As a thread terminates the
     * {@code this.notifyAll} method is invoked. It is recommended that
     * applications not use {@code wait}, {@code notify}, or
     * {@code notifyAll} on {@code Thread} instances.
     *
     * @param  millis
     *         the time to wait in milliseconds
     *
     * @throws  IllegalArgumentException
     *          if the value of {@code millis} is negative
     *
     * @throws  InterruptedException
     *          if any thread has interrupted the current thread. The
     *          <i>interrupted status</i> of the current thread is
     *          cleared when this exception is thrown.
     */
    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;
            }
        }
    }

翻译一下注释:等待millis 毫秒终止线程,假如这段时间内该线程还没执行完,那么结束等待。如果是0,意味着一直等待,知道线程终止。

很明显,有一个while循环使该线程一直停留在阻塞状态,再看一下isAlive()方法:

 /**
     * Tests if this thread is alive. A thread is alive if it has
     * been started and has not yet died.
     *
     * @return  <code>true</code> if this thread is alive;
     *          <code>false</code> otherwise.
     */
    public final native boolean isAlive();

是一个native方法,但是看一下注释:判断该线程是否是正在执行状态,正在执行状态是指已经start了,但是还没结束。

通过不停判断该线程的状态,来决定是不是要wait,线程结束,或者达到指定的延迟时间后,终止代码。

相关文章

  • 线程阻塞(四),join及源码解析

    有一个笔试题,A、B、C三个线程,怎么保证A执行完后再执行B,B执行完后再执行C。 最简单的就是join 了吧。直...

  • 用C++11多线程库thread创建线程

    一、函数方式 threadC++11标准线程库,创建线程: join()mythread.join();阻塞主线程...

  • Threading join()和setDeamon()

    join(timeout=None)在主线程A中创建子线程B,执行B.join(),则主线程将在join处阻塞至子...

  • Python threading 中join()的作用

    Python中join()的作用:(菜鸟网络)join([time]): 等待至线程中止。这阻塞调用线程直至线程的...

  • C多线程 队列

    join,detach thread::join(): 阻塞当前线程,直至 this 所标识的线程完成其执行。th...

  • 线程插队join

    join合并线程,待此线程执行完毕后,再执行其他线程,其他线程阻塞。 join是thread的实例方法

  • Java 面试题

    java多线程实现主线程等待子线程执行完问题 1、使用Thread的join()方法,join()方法会阻塞主线程...

  • 多线程系列08-join()

    join() 的作用:让“主线程”等待“子线程”结束之后才能继续运行。join()源码示例: 源码分析:(01) ...

  • Java线程join()

    join 方法是一个阻塞方法,用来进行线程之间的交流。线程 A 调用 线程 B 的 join 方法,则线程 A 将...

  • SynchronousQueue源码解析

    阻塞队列系列 ArrayBlockingQueue源码解析 LinkedBlockingQueue源码解析 通过上...

网友评论

      本文标题:线程阻塞(四),join及源码解析

      本文链接:https://www.haomeiwen.com/subject/oymgdftx.html