深入Thread.sleep
来源:互联网 发布:java打印方法签名 编辑:程序博客网 时间:2024/06/05 00:51
友情推荐:
- 线程池原理
- 多线程中断机制
- head first Thread.join()
实战分析
一直都说,Threed.sleep是不会释放锁,而wait是释放锁的(对象锁),现理论上来分析一下啊。
由于CPU分配的每个线程的时间片极为短暂(一般为几十毫秒),所以,CPU通过不停地切换线程执行,这样就给程序员一种错觉,以为多个线程是在同时执行。sleep就是正在执行的线程主动让出CPU,CPU去执行其他线程,在sleep指定的时间过后,CPU才会回到这个线程上继续往下执行,如果当前线程进入了同步锁,sleep方法并不会释放锁,即使当前线程使用sleep方法让出了CPU,但其他被同步锁挡住了的线程也无法得到执行。
package thread.concurrent;public class DeepenSleep implements Runnable { private int number = 10; public void firstMethod() throws Exception { synchronized (this) { System. out.println("in first method"); number += 100; System. out.println("+100=" + number); } } public void secondMethod() throws Exception { synchronized (this) { System. out.println("in second method, prepare sleep"); /** * (休息2S,阻塞线程) 以验证当前线程对象的机锁被占用时, 是否被可以访问其他同步代码块 */ Thread. sleep(2000); System. out.println("wake up!!"); // this.wait(2000); number *= 200; System. out.println("*200=" + number); } } @Override public void run() { try { System. out.println("run thread..."); firstMethod(); } catch (Exception e) { e.printStackTrace(); } } public static void main(String[] args) throws Exception { DeepenSleep dt = new DeepenSleep(); Thread thread = new Thread(dt); thread.start(); System. out.println("prepare run second method"); dt.secondMethod(); }}
输出如下:
分析:主线程启动起来,因为创建线程等的资源消耗,所以主线程会先执行 dt.secondMethod(),因此会先输出prepare run second method,其后执行secondMehtod方法(注意该方法是要先闹到锁对象),而该方法直接将线程睡眠2s(注意此处对象锁DeepenSleep的实例对象并没有释放),然后执行线程dt的run方法,该方刚发执行dt的firstMethod,然而,该方法也是需要获取锁对象的,而此时他没先不能获取到,因为secondMehtod没有释放锁(准确点讲,主线程没有释放锁);然后等了2s,主线程睡眠时间已过,他warkup之后,因为还拥有锁,因此直接run secondMethod的剩下的方法,先输出”wake up”,然后执行 number*200,执行完,主线程释放掉锁,而dt线程拿到锁,执行run方法,拿到锁,执行run方法的synchronized的剩余方法:先输出”in first method”,然后执行加100的操作。
我们来变一下将firstMethod的同步去掉,看输出是什么样子
package thread.concurrent;public class DeepenSleep implements Runnable { private int number = 10; public void firstMethod() throws Exception {// synchronized (this) { System. out.println( "in first method"); number += 100; System. out.println( "+100=" + number);// } } public void secondMethod() throws Exception { synchronized ( this) { System. out.println( "in second method, prepare sleep"); /** * (休息2S,阻塞线程) 以验证当前线程对象的机锁被占用时, 是否被可以访问其他同步代码块 */ Thread. sleep(2000); System. out.println( "wake up!!"); // this.wait(2000); number *= 200; System. out.println( "*200=" + number); } } @Override public void run() { try { System. out.println( "run thread..."); firstMethod(); } catch (Exception e) { e.printStackTrace(); } } public static void main(String[] args) throws Exception { DeepenSleep dt = new DeepenSleep(); Thread thread = new Thread(dt); thread.start(); System. out.println( "prepare run second method"); dt.secondMethod(); }}
输出如下:
分析:不同点在于,主线程睡眠之后,没有释放锁,dt线程执行firstMethod并不需要锁,因此先run firstMethod中的逻辑,先加100,然今,主线程睡醒之后,再执行剩下的逻辑,乘以200。
Thread.sleep(1000),1000ms后是否立即执行?
不一定,在未来的1000毫秒内,线程不想再参与到CPU竞争。那么1000毫秒过去之后,这时候也许另外一个线程正在使用CPU,那么这时候操作系统是不会重新分配CPU的,直到那个线程挂起或结束;况且,即使这个时候恰巧轮到操作系统进行CPU 分配,那么当前线程也不一定就是总优先级最高的那个,CPU还是可能被其他线程抢占去。
Thread.sleep(0),是否有用?
boss:“给你睡0小时”。coder:“你TM逗我啊”。
休眠0ms,这样的休眠有何意义?Thread.Sleep(0)的作用,就是“触发操作系统立刻重新进行一次CPU竞争,重新计算优先级”。竞争的结果也许是当前线程仍然获得CPU控制权,也许会换成别的线程获得CPU控制权。这也是我们在大循环里面经常会写一句Thread.sleep(0) ,因为这样就给了其他线程比如Paint线程获得CPU控制权的权力,这样界面就不会假死在那里。
微信扫我^_^
- 深入Thread.sleep
- 深入理解 Thread.Sleep 函数
- Java 线程 sleep wait 深入解析 Thread
- 深入理解Thread.sleep的含义
- 深入理解Thread.sleep()的意义
- thread.sleep()
- Thread.Sleep
- thread.sleep()
- Thread.Sleep
- Thread.sleep() & SystemClock.sleep()
- Thread.sleep() & SystemClock.sleep()
- 对线程调度中Thread.sleep(0)的深入理解
- 对线程调度中Thread.sleep(0)的深入理解
- Thread.sleep()和Thread.currentThread().sleep()区别
- Thread.sleep()和Thread.currentThread().sleep()区别
- Thread.sleep()和Thread.currentThread().sleep()区别
- Thread.sleep 与Thread.currentThread.sleep
- Thread.Join()和Thread.Sleep()
- ELK 之 Logstash
- poj 2107 K-th Number(主席树求区间第K大)
- 每日一题(32)—— 联合体大小
- 关于IE抛出"不能执行已释放 script 的代码"的解决方法
- 图纸转图片cad转换成jpg格式
- 深入Thread.sleep
- SpringMVC源码情操陶冶-FreeMarker之web配置
- 并查集知识
- 解决Android Studio运行时报Error:java.lang.NullPointerException (no error message)错误
- BZOJ 1486: [HNOI2009]最小圈 01分数规划 dfs_spfa判负环
- ThinkPHP5获取header头分析用户行为,有效预防攻击
- 表达式的值
- AngularJS 路由 resolve用法
- Calendar类