• Thread.join()的使用


    代码清单:

    package com.baidu.nuomi.concurrent;
    
    import java.util.concurrent.TimeUnit;
    
    /**
     * Created by sonofelice on 16/6/18.
     */
    public class Join {
        public static void main(String[] args) throws Exception{
            Thread previous = Thread.currentThread();
            for (int i = 0; i < 10; i++) {
                Thread thread = new Thread(new Domino(previous),String.valueOf(i));
                thread.start();
                previous = thread;
            }
            TimeUnit.SECONDS.sleep(5);
            System.out.println(Thread.currentThread().getName() + " terminate.");
        }
        static class Domino implements Runnable{
            private Thread thread;
            public Domino(Thread thread){
                this.thread = thread;
            }
            @Override
            public void run() {
                try {
                    thread.join();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName() + " terminate. ");
            }
        }
    }

    输出结果如下:

    main terminate.
    0 terminate. 
    1 terminate. 
    2 terminate. 
    3 terminate. 
    4 terminate. 
    5 terminate. 
    6 terminate. 
    7 terminate. 
    8 terminate. 
    9 terminate. 
    
    Process finished with exit code 0

    从上述输出可以看到,每个线程终止的前提是前驱线程的终止,每个线程等待前驱线程终止后,才从join方法返回。

    代码中创建了10个线程,0~9,每个线程调用前一个线程的join方法,也就是线程0结束了,线程1才能从join方法中返回,而线程0需要等待main线程结束。

    看一下join方法的源码:

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

    我们调用的join方法没有传参数,就是漂黄的那一段代码,默认millis=0的。

    当线程终止时,会调用线程自身的notifyAll()方法,会通知所有等待在该线程对象上的线程。加锁、循环、处理逻辑。跟上一篇博文中的等待/通知经典范式一致。

  • 相关阅读:
    ORACLE创建数据库时无法创建目录
    KindEditor:Ajax提交表单时获取不到HTML内容
    mysql重置root密码
    假设检验-单样本检验
    推论统计分析-如何避免偏见和抽样分布
    推论统计分析1
    共享单车数据分析
    Kaggle泰坦尼克号生存情况预测
    R-长尾词练习
    R期望
  • 原文地址:https://www.cnblogs.com/sonofelice/p/5596268.html
Copyright © 2020-2023  润新知