Java Thread.sleep(),结合例子只学一次

x33g5p2x  于2022-02-18 转载在 Java  
字(2.7k)|赞(0)|评价(0)|浏览(271)

这个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也是一样效果,就不在写代码举例了。

相关文章