Thread的join()方法

看到一个多线程的编程问题,如何让线程A、B、C顺序执行,即线程A执行完后,线程B开始执行,线程B执行完后,线程C开始执行。
我的实现想法是使用单线程的线程池,依次将RunableA、RunnableB、RunnableC三个Runnable submit()。答案给的是使用Thread的join()方法,编了个程序验证下:

package com.zn.jinma.test;

public class TestJoin {
    public static class RunnableA implements Runnable {
        @Override
        public void run() {
            System.out.println("A thread start to run threadId " + Thread.currentThread().getId());
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("A thread runOver");
        }
    }

    public static class RunnableB implements Runnable {
        @Override
        public void run() {
            System.out.println("B thread start to run threadId " + Thread.currentThread().getId());
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("B thread runOver");
        }
    }

    public static class RunnableC implements Runnable {
        @Override
        public void run() {
            System.out.println("C thread start to run threadId " + Thread.currentThread().getId());
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("C thread runOver");
        }
    }

    public static class WorkerRunable implements Runnable {
        @Override
        public void run() {
            System.out.println("worker runnable start to run threadId " + Thread.currentThread().getId());
            System.out.println();

            Thread threadA = new Thread(new RunnableA());
            threadA.start();
            try {
                threadA.join();
            } catch (InterruptedException e1) {
                e1.printStackTrace();
            }
            System.out.println("worker runnable threadA run over threadId " + Thread.currentThread().getId());

            Thread threadB = new Thread(new RunnableB());
            threadB.start();
            try {
                threadB.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("worker runnable threadb run over threadId " + Thread.currentThread().getId());

            Thread threadC = new Thread(new RunnableC());
            threadC.start();
            try {
                threadC.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            System.out.println("worker runnable threadC run over threadId " + Thread.currentThread().getId());

            System.out.println();
            System.out.println("worker runnable run over threadId " + Thread.currentThread().getId());
        }
    }

    public static void main(String[] args) {
        System.out.println("main thread thread start to run threadId " + Thread.currentThread().getId());

        new Thread(new WorkerRunable()).start();

        System.out.println("main thread run over");
        System.out.println();
    }
}

结果如下:
main thread thread start to run threadId 1
main thread run over

worker runnable start to run threadId 9

A thread start to run threadId 11
A thread runOver
worker runnable threadA run over threadId 9
B thread start to run threadId 12
B thread runOver
worker runnable threadb run over threadId 9
C thread start to run threadId 13
C thread runOver
worker runnable threadC run over threadId 9

worker runnable run over threadId 9
代码思路很简单,主线程中开启工作线程,工作线程中,依次创建线程A、B、C,分别调用它们的start()方法和join()方法。
分析下结果,主线程执行完毕就退出了,工作者线程启动后,线程A、B、C依次开始执行,都执行完后,工作者线程退出执行。
从结果可以看出ThreadA.join()方法的意思是:工作者线程需要等ThreadA执行完毕后,才开始执行。
那么这是如何实现的呢?
看下join()方法(android中):

/**
 * Blocks the current Thread (<code>Thread.currentThread()</code>) until
 * the receiver finishes its execution and dies.
 *
 * @throws InterruptedException if the current thread has been interrupted.
 *         The interrupted status of the current thread will be cleared before the exception is
 *         thrown.
 * @see Object#notifyAll
 * @see java.lang.ThreadDeath
 */
public final void join() throws InterruptedException {
    synchronized (lock) {
        while (isAlive()) {
            lock.wait();
        }
    }
}

其中lock是Thread对象的一个final对象,声明如下:

/**
 * The synchronization object responsible for this thread's join/sleep/park operations.
 */
private final Object lock = new Object();

这样看来join()的方法非常简单,通过ThreadA.lock.wait()方法将join()方法执行所在线程(工作者线程,非ThreadA)阻塞,等到ThreadA执行完毕,ThreadA通过lock.notifyAll()方法将工作者线程唤醒(这里从哪里得出的结论?)工作者线程里isAlive()的判断为false,退出while循环,join()方法执行完毕。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值