Java Thread.join方法

1. Thread.join方法

join()方法会等待指定线程结束,然后才会继续运行。

public class ThreadJoin {

    public static void main(String[] args) {
        try {
            ThreadA threadA = new ThreadA();
            threadA.start();

            System.out.println("In Main begin at " + System.currentTimeMillis());
            threadA.join();
            System.out.println("In Main end at " + System.currentTimeMillis());
        } catch (InterruptedException e) {
        }
    }

    static class ThreadA extends Thread {
        public void run() {
            try {
                System.out.println("In ThreadA begin at " + System.currentTimeMillis());
                Thread.sleep(3000);
                System.out.println("In ThreadA end at " + System.currentTimeMillis());
            } catch (InterruptedException e) {
            }
        }
    }

}

输出
在这里插入图片描述

2. join(long)方法

join(long)方法会等待指定线程一段时间,然后进入运行状态。

将上面的threadA.join()修改成以下代码,

threadA.join(2000);

输出
在这里插入图片描述
如果是等待4秒,在3秒时就返回并结束程序。
在这里插入图片描述

3. join方法解析

join()方法会调用join(0),而join(long)在源码里如此实现。

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

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,直接调用wait(0),否则在等待指定时间后返回。而Thread结束线程后,会调用唤醒所有等待列表中的线程。

public class ThreadFinishWait {

    public static void main(String[] args) {
        ThreadA threadA = new ThreadA();
        threadA.start();

        new ThreadB(threadA).start();
        new ThreadB(threadA).start();
    }

    static class ThreadA extends Thread {

        public void run() {
            try {
                System.out.println("In ThreadA begin at " + System.currentTimeMillis());
                Thread.sleep(2000);
                System.out.println("In ThreadA end at " + System.currentTimeMillis());
            } catch (InterruptedException e) {
            }
        }
    }

    static class ThreadB extends Thread {
        ThreadA threadA;

        public ThreadB(ThreadA threadA) {
            this.threadA = threadA;
        }

        public void run() {
            synchronized (threadA) {
                try {
                    System.out.println("In ThreadB begin at " + System.currentTimeMillis());
                    threadA.wait();
                    System.out.println("In ThreadB end at " + System.currentTimeMillis());
                } catch (InterruptedException e) {
                }
            }
        }
    }
}

输出
在这里插入图片描述
join()方法中调用了线程的wait()方法,因此要小心对线程对象锁的使用,以免造成一些意外。

public class ThreadJoinError {

    public static void main(String[] args) {
        try {
            ThreadA threadA = new ThreadA();
            threadA.start();

            ThreadB threadB = new ThreadB(threadA);
            threadB.start();

            System.out.println("In Main begin at " + System.currentTimeMillis());
            threadA.join();
            System.out.println("In Main end at " + System.currentTimeMillis());
        } catch (InterruptedException e) {
        }
    }

    static class ThreadA extends Thread {
        public void run() {
            try {
                System.out.println("In ThreadA begin at " + System.currentTimeMillis());
                Thread.sleep(2000);
                System.out.println("In ThreadA end at " + System.currentTimeMillis());
            } catch (InterruptedException e) {
            }
        }
    }

    static class ThreadB extends Thread {
        ThreadA threadA;

        ThreadB(ThreadA threadA) {
            this.threadA = threadA;
        }

        public void run() {
            synchronized (threadA) {
                try {
                    System.out.println("In ThreadB begin at " + System.currentTimeMillis());
                    Thread.sleep(5000);
                    System.out.println("In ThreadB end at " + System.currentTimeMillis());
                } catch (InterruptedException e) {
                }
            }
        }
    }

}

输出
在这里插入图片描述
线程ThreadB获取了ThreadA的线程锁,join()方法需要等待ThreadB释放线程锁后才能完成执行。

相关文章
Java Thread.wait和Thread.notify方法
Java Thread.join方法
Java Thread.sleep方法
Java Thread.Interrupt方法
Java Lock对象

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值