java多线程join()详解
来源:互联网 发布:西安seo服务 编辑:程序博客网 时间:2024/06/07 11:56
join()方法的作用:使所属的线程对象A正常执行,而使当前线程B进行无限期的阻塞,执行线程A执行结束销毁以后,线程B才会继续执行。
通过代码理解一下:
package join;public class MyTest {public static void main(String[] args) throws InterruptedException {MyThread mt = new MyThread();mt.start();mt.join();System.out.println("main Thread end:" + System.currentTimeMillis());}}
package join;public class MyThread extends Thread {public void run() {System.out.println("MyThread begin:" + System.currentTimeMillis());try {Thread.sleep(2000);} catch (InterruptedException e) {e.printStackTrace();}}}
可以看出,main线程并没有立刻执行输出,而是等2秒以后,也就是MyThread线程执行结束以后,才继续执行。
join(long)方法:将上面的mt.join()改成mt.join(1000),执行结果
可以看出,mian线程只等待了1秒,并没有等待MyThread线程结束。
join(long)带参数的用法:
public class MyTest2 {public static void main(String[] args) throws InterruptedException {MyThreadA a = new MyThreadA();MyThreadB b = new MyThreadB(a);b.start();b.join(1000);System.out.println("打印1:" + System.currentTimeMillis());a.start();System.out.println("打印2:" + System.currentTimeMillis());}}
public class MyThreadB extends Thread {private MyThreadA a;public MyThreadB() {}public MyThreadB(MyThreadA a) {this.a = a;}public void run() {synchronized (a) {try {System.out.println("MyThreadB 执行了:" + System.currentTimeMillis());Thread.sleep(5000);System.out.println("MyThreadB 执行结束了:" + System.currentTimeMillis());} catch (InterruptedException e) {e.printStackTrace();}}}}
public class MyThreadA extends Thread {public synchronized void run() {try {System.out.println("MyThreadA 执行了:" + System.currentTimeMillis());Thread.sleep(5000);System.out.println("MyThreadA 执行结束:" + System.currentTimeMillis());} catch (InterruptedException e) {e.printStackTrace();}}}
分析下执行过程:
1、main线程执行b.start()方法,b线程处于了就绪状态,此时cpu并没有把时间资源给b线程, 所以main线程接着执行了b.join(1000),main线程阻塞1秒钟。
2、b线程获得了时间资源执行了run()方法,并且获得了线程a的锁。
3、b线程执行sleep(5000),sleep()方法并不会释放锁,此时main线程等待了1秒以后,main线程处于了就绪状态,由于b线程还处于阻塞,因此main线程获得了时间资源,执行了‘打印1’。
4、main线程继续往下执行,调用a对象start(),由于start方法是同步的,因此main线程需要等b线程释放对象a的锁,所以main线程又进入阻塞状态。
5、5秒以后线程b释放对象a的锁,main线程获得了a的锁,执行了a.start()方法,此时a线程处于就绪状态,与第一条类似,main线程优先执行了‘打印2’。
6、最后线程a执行run()方法,5秒后结束
将MyThreadB类稍作修改。
public class MyThreadB extends Thread {private MyThreadA a;public MyThreadB() {}public MyThreadB(MyThreadA a) {this.a = a;}public void run() {try {Thread.sleep(2000);} catch (InterruptedException e1) {e1.printStackTrace();}synchronized (a) {try {System.out.println("MyThreadB 执行了:" + System.currentTimeMillis());Thread.sleep(5000);System.out.println("MyThreadB 执行结束了:" + System.currentTimeMillis());} catch (InterruptedException e) {e.printStackTrace();}}}}
读者可以自行分析此执行结果的过程。
join(long)与sleep(long)的区别:两者最大的区别就在于,join(long)方法是使用wait(long)时间的,因此具有释放锁的效果,而sleep并不会释放锁。
最后附上start(),join()源码
public synchronized void start() { /** * This method is not invoked for the main method thread or "system" * group threads created/set up by the VM. Any new functionality added * to this method in the future may have to also be added to the VM. * * A zero status value corresponds to state "NEW". */ if (threadStatus != 0) throw new IllegalThreadStateException(); group.add(this); start0(); if (stopBeforeStart) { stop0(throwableFromStop);} }
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; }} }可以看出2个方法都是同步的。
- java多线程join()详解
- java多线程中的join方法详解
- java多线程中的join方法详解
- Java多线程之fork/join框架详解
- Java多线程之fork/join框架详解
- JAVA多线程join方法入门详解
- java基本教程之join方法详解 java多线程教程
- java基本教程之join方法详解 java多线程
- java多线程-join方法详解(附面试题)
- Java多线程编程----线程间通信--join()方法详解
- JAVA多线程 join() 方法详解及应用场景
- Java多线程 --- join
- java 多线程之join
- java多线程-join方法
- JAVA多线程之(join)
- java 多线程join
- java多线程join
- java多线程--join函数
- ucosii第一章读书笔记
- Java框架Struts2之初体验(一)
- mybatis IF判断
- ORACLE 树形遍历查询根节点、父节点、子节点
- 放大镜
- java多线程join()详解
- Python 学习笔记之十二——标准库概览 --第Ⅱ部分
- Android轮播图广告——ViewPager基本实现
- Java-编程之美-中国象棋
- Javascript操作select控件大全
- 放大器
- 浅谈 Quartz2D 在开发中的用处 - 画图形
- 嵌入式系统简介
- Docker入门实践(六) 常用操作命令示例汇总