这个sleep的方法大家很常见也很常用,也别是刚开始玩代码的时候,很喜欢测试一些逻辑的时候,sleep一下。
sleep 有啥用:
让线程在我们要它执行的时候执行,如果我们不要,那就让它睡,不占用 CPU 资源。
那么其实在使用多线程的时候,很容易关联到 锁的使用 ,synchronized 和 Lock这些 。
那么该篇文章其实核心内容是想让大家知道,sleep 与 锁资源之间的关系。
问题: 使用sleep时, 锁资源会释放吗?
示例介绍,一步一步来:
首先我们写下简单的测试代码:
public class SleepTest implements Runnable {
private int count = 1;
@SneakyThrows
@Override
public void run() {
while (true) {
if (count < 10) {
Thread.sleep(1000);
}
System.out.println(Thread.currentThread().getName() + "count=" + count);
count++;
if (count > 10) {
break;
}
}
}
}
写个测试的调用代码:
public static void main(String[] args) throws InterruptedException {
SleepTest sleepTest=new SleepTest();
Thread thread1=new Thread(sleepTest);
Thread thread2=new Thread(sleepTest);
thread1.start();
thread2.start();
}
运行效果:
上面这种是还没涉及到锁的情况,不存在锁资源竞争。那么接下来我们改下代码:
@SneakyThrows
@Override
public void run() {
while (true) {
synchronized (this) {
System.out.println("开始了" + Thread.currentThread().getName() + "count=" + count);
if (count < 10) {
Thread.sleep(1000);
}
System.out.println("睡醒了" + Thread.currentThread().getName() + "count=" + count);
count++;
if (count > 10) {
break;
}
System.out.println("这时候执行完一轮,即将会释放锁" + Thread.currentThread().getName());
}
}
}
注意了: 这时候我的 synchronized 加在的地方 注意了!
我是加在while里面的 , 大家看下执行效果:
可以看到,红色是线程 0 ,蓝色是线程1 ,两个线程有交替输出现象。
不是说sleep不会释放锁资源吗?
其实认真看我的代码,我已经打出了一个输出在关键节点:
因为两个线程都进入到了while里面, synchronized 框住的代码里面有sleep,这时候其实真的是不会释放锁资源的,所以看到
开始了Thread-1count=8
睡醒了Thread-1count=8
这时候执行完一轮,即将会释放锁Thread-1
这三阶段都是一段 一段 输出的 。
然后每一段输出完,锁自动释放。 那就是两个线程自由获取锁资源了。
紧接着,我们把synchronized 放在 while 外面 :
这时候的允许结果,无论执行多少次:
可以看到都是先拿到锁资源的线程,先进入自己的锁内代码块执行,就算里面sleep了,也不会释放锁资源,只有等到整个 synchronized 框住的代码块 执行完了,才释放锁资源 ; 然后另一个线程才拿的到锁,去执行相关代码块。
Sleep 不会释放 锁资源!
再继续搞多一个例子,也是更加明了:
private int count = 1;
@SneakyThrows
@Override
public void run() {
synctest();
}
private synchronized void synctest() throws InterruptedException {
System.out.println(Thread.currentThread().getName()+"拿到锁!!!!!!!!!!");
while (true) {
System.out.println("开始了" + Thread.currentThread().getName() + "count=" + count);
if (count < 10) {
Thread.sleep(100);
}
System.out.println("睡醒了" + Thread.currentThread().getName() + "count=" + count);
count++;
if (count > 10) {
System.out.println(Thread.currentThread().getName()+"大过10了,要出去了");
break;
}
}
System.out.println(Thread.currentThread().getName()+"while方法执行完了,把锁释放给别人");
}
}
看看这情况的执行效果 (大家可以自己想一下,看看与实际效果一不一样):
public static void main(String[] args) throws InterruptedException {
SleepTestNew sleepTest=new SleepTestNew();
Thread thread1=new Thread(sleepTest);
Thread thread2=new Thread(sleepTest);
thread1.start();
thread2.start();
}
结果:
可以看到跟上一次效果一样,先拿到锁资源的线程0, 任意妄为,sleep 休息了很久,但是就是不把锁资源让出来, 别人 线程1 只能等到这个线程完全执行完了,才能拿到锁资源,但是此时count已经大于10了,拿到也没意思,只能根据逻辑出来了。
Sleep 不会释放 锁资源!
Sleep 不会释放 锁资源!
Sleep 不会释放 锁资源!
ps: lock也是一样效果,就不在写代码举例了。
版权说明 : 本文为转载文章, 版权归原作者所有 版权申明
原文链接 : https://blog.csdn.net/qq_35387940/article/details/122998542
内容来源于网络,如有侵权,请联系作者删除!