浅析Java的Thread.join函数
2018-08-17 09:39:37来源:博客园 阅读 ()
(一)join参数解析
join(): 即join(0),主线程无限等待子进程结束,主线程方可执行。
join(long millis):主线程需等待子进程*毫秒,主线程方可执行。
(二)join源码
join函数用了synchronized关键字,即为同步,线程安全。
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 案例分析
自定义线程函数,方便查看结果比较函数效果
public class ThreadJoin extends Thread { public ThreadJoin(String name) { super(name); } @Override public void run(){ for(int i=0;i<10;i++){ System.out.println("i:" + i + ", name:" + this.getName()); } } }
【测试一】.线程无join()
public class ThreadJoinTest { public static void main(String [] args)throws InterruptedException { ThreadJoin threadOne = new ThreadJoin("晓东"); ThreadJoin threadTwo = new ThreadJoin("小明"); System.out.println("---Test start---"); threadOne.start(); threadTwo.start(); System.out.println("---Test end---"); } }
运行结果:
---Test start--- ---Test end--- i:0, name:晓东 i:0, name:小明 i:1, name:小明 i:2, name:小明 i:1, name:晓东 i:3, name:小明 i:4, name:小明 i:2, name:晓东 i:5, name:小明 i:6, name:小明 i:3, name:晓东 i:7, name:小明 i:4, name:晓东 i:5, name:晓东 i:6, name:晓东 i:7, name:晓东 i:8, name:晓东 i:9, name:晓东 i:8, name:小明 i:9, name:小明
总结:Main线程先执行,然后threadOne和threadTwo子进程随机执行,当谁抢占CPU资源的时候,即执行System.out.println("i:" + i + ", name:" + this.getName())。由于线程抢占资源
不确定性,所以两个子进程的执行顺序不一,重复运行的结果也不一样。
【测试二】.线程join()
public class ThreadJoinTest { public static void main(String [] args)throws InterruptedException { ThreadJoin threadOne = new ThreadJoin("晓东"); ThreadJoin threadTwo = new ThreadJoin("小明"); System.out.println("---Test start---"); threadOne.start(); threadTwo.start(); threadOne.join(); threadTwo.join(); System.out.println("---Test end---"); } }
运行结果:
---Test start--- i:0, name:晓东 i:0, name:小明 i:1, name:小明 i:2, name:小明 i:1, name:晓东 i:3, name:小明 i:2, name:晓东 i:3, name:晓东 i:4, name:小明 i:4, name:晓东 i:5, name:小明 i:5, name:晓东 i:6, name:小明 i:6, name:晓东 i:7, name:晓东 i:8, name:晓东 i:9, name:晓东 i:7, name:小明 i:8, name:小明 i:9, name:小明 ---Test end---
总结:可以看出Main主进程先执行start,然后执行两个子进程,最后执行Main主进程的end。所以这个可以看出,主线程必须等到子进程都结束后,才执行。同样子进程的运行顺序也是不一样的。
这里需要注意下,子进程的join()是让正在运行的父亲进程(即Main主进程)进入等待,而不是new thread的子进程进入等待。即让正在运行的进程进入等待。
【测试三】.线程join()在子进程开始运行之前和开始运行之后是否有差异
public class ThreadJoinTest { public static void main(String [] args)throws InterruptedException { ThreadJoin threadOne = new ThreadJoin("晓东"); ThreadJoin threadTwo = new ThreadJoin("小明"); System.out.println("---Test start---"); threadOne.join(); threadTwo.join(); threadOne.start(); threadTwo.start(); System.out.println("---Test end---"); } }
运行结果:
---Test start--- ---Test end--- i:0, name:晓东 i:0, name:小明 i:1, name:晓东 i:1, name:小明 i:2, name:晓东 i:3, name:晓东 i:2, name:小明 i:4, name:晓东 i:3, name:小明 i:4, name:小明 i:5, name:小明 i:5, name:晓东 i:6, name:小明 i:6, name:晓东 i:7, name:小明 i:7, name:晓东 i:8, name:小明 i:8, name:晓东 i:9, name:小明 i:9, name:晓东
总结:可以看出运行结果和无join()的【测试一】是一样的。所以start()前执行join()无效,类似于只执行start()
【测试四】join()和join(**)区别
代码一:
public class ThreadJoin extends Thread { public ThreadJoin(String name) { super(name); } @Override public void run(){ for(int i=0;i<100;i++){ System.out.println("i:" + i + ", name:" + this.getName()); } } } public class ThreadJoinTest { public static void main(String [] args)throws InterruptedException { ThreadJoin threadOne = new ThreadJoin("晓东"); ThreadJoin threadTwo = new ThreadJoin("小明"); System.out.println("---Test start---"); threadOne.start(); threadTwo.start(); threadOne.join(0); System.out.println("---Test end---"); } }
代码二:
public class ThreadJoin extends Thread { public ThreadJoin(String name) { super(name); } @Override public void run(){ for(int i=0;i<100;i++){ System.out.println("i:" + i + ", name:" + this.getName()); } } } public class ThreadJoinTest { public static void main(String [] args)throws InterruptedException { ThreadJoin threadOne = new ThreadJoin("晓东"); ThreadJoin threadTwo = new ThreadJoin("小明"); System.out.println("---Test start---"); threadOne.start(); threadTwo.start(); threadOne.join(1); System.out.println("---Test end---"); } }
代码二运行结果:
---Test start--- i:0, name:晓东 i:0, name:小明 i:1, name:小明 i:2, name:小明 i:1, name:晓东 i:3, name:小明 i:2, name:晓东 i:4, name:小明 i:3, name:晓东 i:5, name:小明 i:4, name:晓东 i:6, name:小明 i:5, name:晓东 i:7, name:小明 i:8, name:小明 i:9, name:小明 i:10, name:小明 i:6, name:晓东 i:11, name:小明 i:7, name:晓东 i:8, name:晓东 i:9, name:晓东 i:10, name:晓东 i:11, name:晓东 i:12, name:晓东 i:12, name:小明 i:13, name:晓东 i:13, name:小明 i:14, name:小明 i:15, name:小明 ---Test end--- i:14, name:晓东 i:16, name:小明 i:15, name:晓东 i:17, name:小明 i:16, name:晓东 i:18, name:小明
...
运行结果:不一样。
代码一:先执行主线程start,然后执行两个子线程,最后执行主线程end。
代码二:先执行主线程start,然后执行两个子线程部分,主线程睡眠1毫秒唤醒后,执行主线程end,再执行两个子线程剩下部分。
总结:join()无限等待子进程结束, join(*毫秒)主线程只是等待子进程*毫秒。
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
上一篇:JavaScript 简介
- 国外程序员整理的Java资源大全(全部是干货) 2020-06-12
- 2020年深圳中国平安各部门Java中级面试真题合集(附答案) 2020-06-11
- 2020年java就业前景 2020-06-11
- 04.Java基础语法 2020-06-11
- Java--反射(框架设计的灵魂)案例 2020-06-11
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash