thread.join,理解与实例(一)

版权声明:本文为博主原创文章,转载请说明出处 https://blog.csdn.net/u010002184/article/details/82907406

java多线程编程join的作用是等待线程结束,这个作用可以产生很多特定的场景。 
1)A线程中调用B线程的join方法,那么A线程需要等待B线程执行完成后才能完成 
2)主线程中依次调用A线程的join方法,B线程的join方法,可以保证A,B线程顺序执行;

是主线程进入等待状态,子线程在运行,子线程运行完成后会通知主线程继续运行,或者join也可以设置主线程的等待时间,当主线程等待超时时,即使子线程没有运行完,主线程也会开始继续执行,

实例1:

public class JoinTest1 {

    public static void main(String[] args) throws InterruptedException {
        Thread t1 = new Thread(new MyRunnable(), "t1");
        t1.start();

        new JoinTest1().listAllThread();

//        t1.join();//等价于t1.join(0);一直等待到线程t1结束,主线程才继续运行
//        t1.join(1000);//线程t1等待1s后,会超时,此时t1没结束,主线程此时会继续运行
        t1.join(6000);//线程t1的等待时间大于运行时间,t1运行结束后,主线程才继续运行,不必等待6s
//        t1.join(3000);//两个时间一致,线程t1运行结束后,主线程才继续运行

        new JoinTest1().listAllThread();

        System.out.println(new Date() + "主线程");

    }


    /**
     * 显示该程序的所有线程
     */
    public void listAllThread() {
        System.out.println(new Date() + " listAllThread...");
        ThreadGroup currentGroup =
                Thread.currentThread().getThreadGroup();
        int noThreads = currentGroup.activeCount();
        Thread[] lstThreads = new Thread[noThreads];
        currentGroup.enumerate(lstThreads);
        for (int i = 0; i < noThreads; i++)
            System.out.println("线程号:" + i + " = " + lstThreads[i].getName());
    }
}


class MyRunnable implements Runnable {
    @Override
    public void run() {
        try {
            Thread.sleep(3000);//模拟使线程运行3s
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

输出:

t1.join();
Sun Sep 30 11:22:01 CST 2018 listAllThread...
线程号:0 = main
线程号:1 = t1
Sun Sep 30 11:22:04 CST 2018 listAllThread...
线程号:0 = main
Sun Sep 30 11:22:04 CST 2018主线程
//线程t1已结束


t1.join(1000);
Sun Sep 30 11:22:42 CST 2018 listAllThread...
线程号:0 = main
线程号:1 = t1
Sun Sep 30 11:22:43 CST 2018 listAllThread...
线程号:0 = main
线程号:1 = t1 //线程t1仍然存活
Sun Sep 30 11:22:43 CST 2018主线程

t1.join(6000);
Sun Sep 30 11:25:18 CST 2018 listAllThread...
线程号:0 = main
线程号:1 = t1
Sun Sep 30 11:25:21 CST 2018 listAllThread...
线程号:0 = main
Sun Sep 30 11:25:21 CST 2018主线程
//线程t1已结束

t1.join(3000);
Sun Sep 30 11:36:43 CST 2018 listAllThread...
线程号:0 = main
线程号:1 = t1
Sun Sep 30 11:36:46 CST 2018 listAllThread...
线程号:0 = main
Sun Sep 30 11:36:46 CST 2018主线程
//线程t1已结束

join源码,java1.8:

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

可见另一篇博客:

《thread.join,理解与实例(二)》https://blog.csdn.net/u010002184/article/details/82910229

猜你喜欢

转载自blog.csdn.net/u010002184/article/details/82907406