深入Thread.sleep

来源:互联网 发布:java打印方法签名 编辑:程序博客网 时间:2024/06/05 00:51

友情推荐:

  1. 线程池原理
  2. 多线程中断机制
  3. 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控制权的权力,这样界面就不会假死在那里。

微信扫我^_^

这里写图片描述

原创粉丝点击