前言
sleep() 休眠,在 synchronized{...}同步代码块 里/外 执行,有着千然之别,接下来我们以实际例子来介绍一下他们之间又如何差别。
本例中 TimeUnit.SECONDS.sleep(1) 与 Thread.sleep(1000) 都是休眠 1s,前者只是对后者进行了一层封装。前者底层的实现还是调用的后者。
实例
1.sleep() 在 synchronized{...} 代码块 外 执行
public class Demo implements Runnable{
//定义一把锁
private static Object lock = new Object();
private static boolean stop = false;
@Override
public void run() {
int i = 0;
synchronized (lock) {
while (!stop) {
System.out.println("11111");
i++;
}
}
}
public static void main(String[] args) throws InterruptedException {
//开启线程
Thread thread1 = new Thread(new VisableDemo());
thread1.start();
//(sleep在外执行)休眠1s,等待新启线程执行
TimeUnit.SECONDS.sleep(1);
synchronized (lock) {
stop = true;
}
}
}
测试结果:
①thread 线程会持续1s输出"11111"
②线程不会停止
原因:
sleep(long millis)休眠,必须是当前线程调用此方法,sleep在 synchroinzed{...}外执行,相当于 main 主线程调用了 sleep()方法,此时 main 主线程进入到 TIMED_WAITING 状态,但不会释放对象锁。本例中休眠 1s 以后,线程会自动苏醒,并进入到就绪状态。
sleep作用:让当前线程进入就绪状态,给其它线程执行机会的最佳方式。
此时 main主线程会等待 thread1 线程结束,再次执行 synchronized{...}代码块中的代码 stop = true;
然而,thread1线程是一个while(true)死循环,所以,thread1 线程不会停止,从而导致 synchronized{...}代码块中的代码永远不会执行,从而 thread1 线程就会那样一直死循环下去了。
2.sleep() 在 synchronized{...} 代码块 内 执行
public class Demo implements Runnable{
//定义一把锁
private static Object lock = new Object();
private static boolean stop = false;
@Override
public void run() {
int i = 0;
synchronized (lock) {
while (!stop) {
System.out.println("11111");
i++;
}
}
}
public static void main(String[] args) throws InterruptedException {
//开启多线程
Thread thread1 = new Thread(new VisableDemo());
thread1.start();
synchronized (lock) {
//(sleep在里执行)休眠1s,等待新启线程执行
TimeUnit.SECONDS.sleep(1);
stop = true;
}
}
}
测试结果:
①thread 线程会持续1s输出"11111"
②线程不会停止
原因:
sleep(long millis)休眠,必须是当前线程调用此方法。线程启动是需要时间的,此时 thread1 线程并没有启动起来时,已经进入到了 synchronized{...} 代码块内执行。
当执行 sleep(1) 休眠时,此时 main 主线程获得锁之后,就算是 thread1此时已经启动,也是无法获取到锁,此时thread1 线程会等待 main 主线程休眠完 1s ,执行完 stop = true;后。此时 main 主线程释放锁,thread1 线程则会获得这把锁,获得这把锁后,thread1 线程开始执行。
但是,thread1 线程发现 !stop 已经是 false了,thread1 线程会说:我这还没开始就中途夭折了。所以 thread1 线程就这样结束了自己的生命。
sleep()方法在synchronized代码块 里/外的区别,介绍到此为止
如果本文对你有所帮助,那就给我点个赞呗 ^_^
End