多线程学习-基础(四)常用函数说明:sleep-join-yield
一、常用函数的使用
(1)Thread.sleep(long millis):在指定的毫秒内让当前正在执行的线程休眠(暂停执行),休眠时不会释放当前所持有的对象的锁。
(2)join():主线程等待子线程终止后才可以终止
使用方式:
join()是Thread的一个方法,启动线程后可以直接调用,即join()的作用是:“等待该线程终止”,这里需要解释的是“该线程终止”是指主线程等待子线程的终止。
Thread t = new AThread();t.start();t.join();
为什么要用join()方法:
在很多情况下,主线程生成并启动了子线程,如果子线程要进行大量的耗时运算,主线程往往在子线程之前结束,但是如果主线程处理完其他事务后,需要用到子线程的处理结果,也就是说主线程需要等待子线程结束之后才可以结束,这个时候就需要用到join()方法了。
测试案例:
不加join()方法
package com.jason.comfuns.join; /*** 多线程学习* @function 不使用Thread.join()方法:测试在主线程中启动子线程时:主子线程的执行顺序* @author 小风微凉* @time 2018-4-21 下午12:56:31*/ public class Thread_join_Action extends Thread {private String thname;public Thread_join_Action(String name){super(name);this.thname=name;}public void run(){System.out.println(Thread.currentThread().getName()+"线程运行开始!");for(int i=0;i<5;i++){System.out.println("子线程"+thname+"运行:"+i);try {sleep((int)Math.random()*10);} catch (InterruptedException e) {e.printStackTrace();}}System.out.println(Thread.currentThread().getName()+"线程运行结束!");}/*** 启动测试程序* @param args*/public static void main(String[] args) {System.out.println(Thread.currentThread().getName()+"主线程运行开始!");Thread_join_Action thread1=new Thread_join_Action("A");Thread_join_Action thread2=new Thread_join_Action("B");thread1.start();thread2.start();System.out.println(Thread.currentThread().getName()+"主线程运行结束!");} }
运行结果:(主线程:main在子线程A和子线程B之前结束了)
main主线程运行开始!
main主线程运行结束!
A线程运行开始!
子线程A运行:0
B线程运行开始!
子线程B运行:0
子线程A运行:1
子线程B运行:1
子线程A运行:2
子线程B运行:2
子线程A运行:3
子线程B运行:3
子线程A运行:4
子线程B运行:4
A线程运行结束!
B线程运行结束!
加入join():(所有子线程都调用join())
测试案例:
package com.jason.comfuns.join; /*** 多线程学习* @function 不使用Thread.join()方法:测试在主线程中启动子线程时:主子线程的执行顺序* @author 小风微凉* @time 2018-4-21 下午12:56:31*/ public class Thread_join_Action extends Thread {private String thname;public Thread_join_Action(String name){super(name);this.thname=name;}public void run(){System.out.println(Thread.currentThread().getName()+"线程运行开始!");for(int i=0;i<5;i++){System.out.println("子线程"+thname+"运行:"+i);try {sleep((int)Math.random()*10);} catch (InterruptedException e) {e.printStackTrace();}}System.out.println(Thread.currentThread().getName()+"线程运行结束!");}/*** 启动测试程序* @param args*/public static void main(String[] args) {System.out.println(Thread.currentThread().getName()+"主线程运行开始!");Thread_join_Action thread1=new Thread_join_Action("A");Thread_join_Action thread2=new Thread_join_Action("B");thread1.start();thread2.start();//开始调用子线程thread1的join()try {thread1.join();} catch (InterruptedException e) {e.printStackTrace();}//开始调用子线程thread2的join()try {thread2.join();} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread().getName()+"主线程运行结束!");} }
运行结果:
执行结果:(主线程main,在子线程A和子线程B执行结束之后,才结束,前提:子线程A和子线程B都必须调用join())
main主线程运行开始!
A线程运行开始!
B线程运行开始!
子线程B运行:0
子线程A运行:0
子线程B运行:1
子线程A运行:1
子线程B运行:2
子线程B运行:3
子线程A运行:2
子线程B运行:4
子线程A运行:3
B线程运行结束!
子线程A运行:4
A线程运行结束!
main主线程运行结束!
加入join():(部分子线程都调用join())
测试案例:
package com.jason.comfuns.join; /*** 多线程学习* @function 不使用Thread.join()方法:测试在主线程中启动子线程时:主子线程的执行顺序* @author 小风微凉* @time 2018-4-21 下午12:56:31*/ public class Thread_join_Action extends Thread {private String thname;public Thread_join_Action(String name){super(name);this.thname=name;}public void run(){System.out.println(Thread.currentThread().getName()+"线程运行开始!");for(int i=0;i<5;i++){System.out.println("子线程"+thname+"运行:"+i);try {sleep((int)Math.random()*10);} catch (InterruptedException e) {e.printStackTrace();}}System.out.println(Thread.currentThread().getName()+"线程运行结束!");}/*** 启动测试程序* @param args*/public static void main(String[] args) { System.out.println(Thread.currentThread().getName()+"主程序运行开始!");Thread_join_Action thread1=new Thread_join_Action("A");Thread_join_Action thread2=new Thread_join_Action("B");thread1.start();thread2.start();//开始调用子线程thread1的join()------只有子线程A调用join()try {thread1.join();} catch (InterruptedException e) {e.printStackTrace();} System.out.println(Thread.currentThread().getName()+"主程序运行结束!"); } }
运行结果:(只有在主线程中的调用了join()方法的子线程运行结束,主线程才会结束,没有调用join()方法的子线程不在此列)
main主程序运行开始!
B线程运行开始!
A线程运行开始!
子线程A运行:0
子线程B运行:0
子线程A运行:1
子线程B运行:1
子线程A运行:2
子线程B运行:2
子线程A运行:3
子线程B运行:3
子线程A运行:4
子线程B运行:4
A线程运行结束!
main主程序运行结束!
B线程运行结束!
(3)yield():暂停当前正在执行的线程,并执行其他线程。
Thread.yield():暂停当前正在执行的线程,并执行其他线程。
yield()方法应该做的是让当前行线程回到可运行状态(就绪状态),以允许其他相同优先级或更高优先级的线程获得运行机会。因此,使用yield()方法的目的是让相同优先级的线程之间能够适当的轮转执行。但是,实际上无法保证yield()达到让步目的,因为让步线程(yield()的调用对象线程)还有可能被线程调度程序再次选中。
结论:
yield()从未导致:线程转到等待、休眠、阻塞状态。在大多数情况下,yield()将导致线程从运行状态转到可运行状态(就绪状态),但是有可能没效果。
简单案例: (测试2个同优先级别的线程:在调用yield()方法时的执行情况)
package com.jason.comfuns.yield; /*** 多线程学习* @function * @author 小风微凉* @time 2018-4-21 下午1:53:37* 总结:* 当一个线程调用yield(),那么当前运行线程会让出cpu执行权限,供自己其他同优先级别活更高的优先级别的线程抢夺。* 谁(线程)抢到,谁开始运行。*/ public class Thread_yield_Action extends Thread{private String thname;public Thread_yield_Action(String name){super(name);this.thname=name;}public void run(){System.out.println(Thread.currentThread().getName()+"线程运行开始");for(int i=0;i<10;i++){System.out.println(Thread.currentThread().getName()+"线程运行:"+i);if(i==5){//当i为5时,该线程会让出CPU的执行机会,让其他或自己的线程执行。(简单来说:谁抢到CPU的权限谁执行)System.out.println(Thread.currentThread().getName()+"让出CPU权限-------------");Thread.yield();//或者this.yield() }} System.out.println(Thread.currentThread().getName()+"线程运行结束");}public static void main(String[] args) {Thread_yield_Action thread1=new Thread_yield_Action("A");Thread_yield_Action thread2=new Thread_yield_Action("B");thread1.start();thread2.start();} }
运行结果:
运行结果:(当一个线程执行yield()后就让出cpu执行权限,供其他同优先级或自己的线程竞争抢夺)
B线程运行开始
A线程运行开始
A线程运行:0
A线程运行:1
A线程运行:2
B线程运行:0
A线程运行:3
A线程运行:4
A线程运行:5
A让出CPU权限-------------
B线程运行:1
B线程运行:2
B线程运行:3
B线程运行:4
B线程运行:5
A线程运行:6
A线程运行:7
A线程运行:8
A线程运行:9
B让出CPU权限-------------
A线程运行结束
B线程运行:6
B线程运行:7
B线程运行:8
B线程运行:9
B线程运行结束
简单案例:(测试:2个线程,一个优先级10 , 一个优先级5,让优先级10的线程主动让出CPU的执行权限,检测执行情况)
package com.jason.comfuns.yield; /*** 多线程学习* @function 测试: yield()方法* @author 小风微凉* @time 2018-4-21 下午1:53:37* 总结:* 当一个线程调用yield(),那么当前运行线程会让出cpu执行权限,供自己其他同优先级别活更高的优先级别的线程抢夺。* 谁(线程)抢到,谁开始运行。*/ public class Thread_yield_Action extends Thread{private String thname;public Thread_yield_Action(String name){super(name);this.thname=name;}public void run(){System.out.println(Thread.currentThread().getName()+"线程运行开始");for(int i=0;i<10;i++){System.out.println(Thread.currentThread().getName()+"线程运行:"+i);if(i==5){//当i为5时,该线程会让出CPU的执行机会,让其他或自己的线程执行。(简单来说:谁抢到CPU的权限谁执行) if("A".equals(Thread.currentThread().getName())){//如果是优先级大的则yield执行一次退让System.out.println(Thread.currentThread().getName()+"让出CPU权限-------------");Thread.yield();//或者this.yield() } }} System.out.println(Thread.currentThread().getName()+"线程运行结束");}public static void main(String[] args) {Thread_yield_Action thread1=new Thread_yield_Action("A");Thread_yield_Action thread2=new Thread_yield_Action("B"); thread1.setPriority(MAX_PRIORITY);//优先级:10thread1.start();thread2.setPriority(MIN_PRIORITY);//优先级:5thread2.start(); } }
运行结果:(总结:A的优先级为10级,B的优先级为5级,即使A的线程调用了yield()方法,让出了cpu的执行权,从执行状态退到了可执行状态,但是由于目前之后线程A和线程B,还是会优先调度线程A)
A线程运行开始
A线程运行:0
A线程运行:1
A线程运行:2
B线程运行开始
A线程运行:3
A线程运行:4
A线程运行:5
A让出CPU权限-------------
B线程运行:0
A线程运行:6
A线程运行:7
A线程运行:8
A线程运行:9
A线程运行结束
B线程运行:1
B线程运行:2
B线程运行:3
B线程运行:4
B线程运行:5
B线程运行:6
B线程运行:7
B线程运行:8
B线程运行:9
B线程运行结束
简单案例:(测试:2个线程,一个优先级10 , 一个优先级5,让优先级5的线程主动让出CPU的执行权限,检测执行情况)
修改上面部分代码:
public static void main(String[] args) {Thread_yield_Action thread1=new Thread_yield_Action("A");Thread_yield_Action thread2=new Thread_yield_Action("B");Thread_yield_Action thread3=new Thread_yield_Action("C");thread1.setPriority(MIN_PRIORITY);//5级 thread1.start();thread2.setPriority(MAX_PRIORITY);//10级 thread2.start();thread3.setPriority(2);//2级 thread3.start();}
运行结果:(总结:A的优先级为5级,B的优先级为10级,此时由于B的优先级高于A,B已经先行执行完毕了,然后A的线程调用了yield()方法,让出了cpu的执行权,此时只剩下A线程和C线程,由于A线程优先级别高于C线程,则仍然会优先执行A线程,最后C线程)
B线程运行开始
B线程运行:0
B线程运行:1
B线程运行:2
B线程运行:3
B线程运行:4
B线程运行:5
B线程运行:6
B线程运行:7
B线程运行:8
B线程运行:9
B线程运行结束
A线程运行开始
A线程运行:0
A线程运行:1
A线程运行:2
A线程运行:3
A线程运行:4
A线程运行:5
A让出CPU权限-------------
A线程运行:6
A线程运行:7
A线程运行:8
A线程运行:9
A线程运行结束
C线程运行开始
C线程运行:0
C线程运行:1
C线程运行:2
C线程运行:3
C线程运行:4
C线程运行:5
C线程运行:6
C线程运行:7
C线程运行:8
C线程运行:9
C线程运行结束
转载于:https://www.cnblogs.com/newwind/p/8902108.html
多线程学习-基础(四)常用函数说明:sleep-join-yield相关推荐
- 数字化方法基础_常用函数
数字化方法基础_常用函数 1. 叉乘 2. 单位化矢量 3. 矩阵乘法4×4 × 4×1 4. 矩阵乘法 4×4 × 4×4 1. 叉乘 void crossproject(float vec1[3] ...
- jquery学习笔记及常用函数封装
二.JQuery 学习笔记及常用函数封装 https://download.csdn.net/download/weixin_42530002/13087988 1.JQuery入门 (1).css选 ...
- Python语言学习:Python语言学习之正则表达式常用函数之re.search方法【输出仅一个匹配结果(内容+位置)】、re.findall方法【输出所有匹配结果(内容)】案例集合之详细攻略
Python语言学习:Python语言学习之正则表达式常用函数之re.search方法[输出仅一个匹配结果(内容+位置)].re.findall方法[输出所有匹配结果(内容)]案例集合之详细攻略 导读 ...
- 【转】JNI学习积累之一 ---- 常用函数大全
原文网址:http://blog.csdn.net/qinjuning/article/details/7595104 本文原创,转载请注明出处:http://blog.csdn.net/qinjun ...
- JNI学习积累之一 ---- 常用函数大全
本文原创,转载请注明出处:http://blog.csdn.NET/qinjuning 最近一段时间,在工作方面比较闲,分配的Bug不是很多,于是好好利用这段时间就着源代码看了些许模块, 主要方式 还 ...
- Arduino基础与常用函数
文章目录 1. Arduino语言 2. Arduino代码结构 1.类似于C的头文件包含,变量定义等 2.void setup() 3.void loop() 3.串口常用函数 1.串口收发函数 S ...
- CDA学习之Pandas - 常用函数和75个高频操作
目录 一.函数 1.1 常用函数 1.1.1 导⼊数据 1.1.2 导出数据 1.1.3 查看数据 1.1.4 数据选取 1.1.5 数据处理 1.1.6 数据分组和排序 1.1.7 数据合并 1.1 ...
- Python_7分钟笔记_基础四(函数、递归)
本期笔记内容综述 Python函数定义再回顾 函数的参数传递 Python函数递归问题 7分钟学习系列 1.Python函数再回顾 著名的斐波拉契数列 除了第一个数和第二个数外,任意一个数都可由前两个 ...
- DAX圣经学习笔记1 - 常用函数
目录 一.常用函数 聚合函数 逻辑函数 信息函数 算术函数 三角函数 文本函数 一.常用函数 聚合函数 区分计数函数 Comment COUNT 数字类型 COUNTA 所有类型 COUNTBLANK ...
最新文章
- android中的json二之json的读写
- 七骑士android版上线时间,腾讯独代韩手游《七骑士》今日全面公测
- yolov3 anchor 理解
- Ubuntu下的第一个博客
- Codeforces Round #742 (Div. 2) F. One-Four Overload 构造 + 二分图染色
- Spring Hibernate教程
- em算法示例_带有示例HTML'em'标签
- 面试题:彻底搞懂 Cookie 和 Session
- 《计算机网络:自顶向下方法(原书第6版)》一2.7 TCP套接字编程
- python中模块文件的扩展名不一定是py_python模块和python包有什么区别?
- [转载] python十个程序_程序猿开发Python的十个基本入门技巧?
- 6.MongoDB之索引
- 参考阿里规范,优秀的 Java 项目代码该如何分层?
- 厉害了,Netty 轻松实现文件上传!
- Kconfig配置文件
- 第五章 数组及排序 ① 笔记
- 从零开始搭建完整的电影全栈系统(六)——影片Api示例、说明及应用
- 南工院计算机答辩,人工智能与计算机学院举行“智能之星”评选答辩会
- python3 中_pickle (cPickle) 序列化 (Serialization)
- 【Python数据分析学习笔记Day3】(三)数据分析工具pandas,数据清洗,聚类K-Means
热门文章
- 深入了解MyBatis返回值
- 用JavaScript玩转计算机图形学(二)基本光源
- OpenCV学习笔记(十六)——CamShift研究 OpenCV学习笔记(十七)——运动分析和物体跟踪Video OpenCV学习笔记(十八)——图像的各种变换(cvtColor*+)imgproc
- CVPR 2015 papers
- springcloud13---zuul
- 自己动手开发智能聊天机器人完全指南(附python完整源码)
- js 中的break continue return
- 如何判断UIWebView是否loading完全
- Cracking the coding interview--Q1.5
- ARM开发培训的总结报告