多线程笔记(十五):sleep() 方法在synchronized代码块 里/外的区别

前言    

        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;
        }
    }
}

测试结果:

扫描二维码关注公众号,回复: 8974381 查看本文章

        ①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

发布了247 篇原创文章 · 获赞 44 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/lzb348110175/article/details/103626835