Java中关于Thread.sleep()与 线程对象.sleep()的思考
前言:java中Thread线程类中的sleep()查看API文档如下:
得知该方法为静态方法,返回值为void,并且有两种传参方式,作用是使当前正在执行的线程以指定的毫秒数暂停,进入睡眠阻塞状态,放弃CPU时间片执行权。
然后我不禁陷入了思考:为啥是静态方法,静态方法一般可用类名直接调用。但是我如果创建一个线程对象,然后用该对象来调用该静态方法会产生咋样的结果?
1.首先,我先用类名直接调用,代码如下:
import java.lang.Thread; public class ThreadTest03{ public static void main(String[] args) { //创建分支线程对象 Thread t3=new MyThread03(); //类名.sleep() try{ Thread.sleep(1000*5); }catch(InterruptedException e){ e.printStackTrace(); } t3.start(); //启动分支线程 } } class MyThread03 extends Thread{ public void run(){ for(int i=0;i<100;i++) System.out.println("当前分支线程--->"+i); } }
Thread.sleep()的作用就是让当前线程进入睡眠,请注意了,是当前线程对象,这个“当前”就很微妙哈哈,有点类似于关键字“this”。通俗解释是:Thread.sleep()出现在哪里,那么哪里就得sleep!
你看,上面的Thread.sleep()不是出现在main方法中吗,所以自然而然 主线程这个“倒霉蛋”只能乖乖的睡眠1000*5ms=5s后再继续执行下一条代码t3.start(),然后才开启分支线程。
2.然后,那如果我想要t3这个线程对象sleep一段时间,那要咋做呢,我立马想到了把Thread.sleep(1000*5)改成t3.sleep(1000*5)岂不是大功告成了?
import java.lang.Thread; public class ThreadTest03{ public static void main(String[] args) { //创建分支线程对象 Thread t3=new MyThread03(); //线程对象.sleep() try{ //在main中,我想这样让t3睡眠行不行 t3.sleep(1000*5); }catch(InterruptedException e){ e.printStackTrace(); } t3.start(); //启动分支线程 } } class MyThread03 extends Thread{ public void run(){ for(int i=0;i<100;i++) System.out.println("当前分支线程--->"+i); } }
实际上,在main线程中使用另一个线程对象t调用sleep()方法是无法达到使得t线程对象sleep的目的的!
原因如下: 在静态方法中, 对象.静态方法 最终会自动转换为类名.静态方法 。
就比如,我定义了一个“人”类,定义了这个类的一个静态方法:“打闪电五连鞭”,然后我创建了一个对象“马保国”, 这个对象去调用静态方法:马保国.打闪电五连鞭。最终执行时会自动转换成 人.打闪电五连鞭 ,表面上看起来是马保国打,实际上并不是。(这时候马保国开始说了:年轻人不讲武德,你骗,欺负我一个69岁的老人。)
所以, t3.sleep()最终会自动转换为Thread.sleep()执行(代表当前对象进入睡眠),表面上是t3进入sleep,实际上还是主线程main进入睡眠5s。
sleep()设置为静态方法的目的: 如果让sleep()成为实例方法,当前线程可以直接sleep别的线程,会引入很多多线程的问题,比如死锁。
所以最终得出结论:只能控制当前正在运行的线程,跟对象调用还是类名调用无关,只看你sleep()出现的位置。
参考学习视频: