并发编程之 sleep 与 yield的详细解析

本文详细探讨了Java中`sleep`和`yield`的使用,以及它们如何影响线程的阻塞、就绪和调度。特别强调了`Thread.sleep`与`TimeUnit.sleep`的区别和线程优先级的作用。测试结果显示,虽然优先级和yield对CPU时间片有影响,但效果有限。
摘要由CSDN通过智能技术生成

3.7 sleep 与 yield

sleep

  1. 调用 sleep 会让当前线程从 Running 进入 Timed Waiting 状态(阻塞)

  2. 其它线程可以使用 interrupt 方法打断正在睡眠的线程,这时 sleep 方法会抛出 InterruptedException

    public static void main(String[] args) throws InterruptedException {
        Thread t1 = new Thread("t1") {
            @Override
            public void run() {
                log.debug("enter sleep...");
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    log.debug("wake up...");
                    e.printStackTrace();
                }
            }
        };
        t1.start();
    ​
        Thread.sleep(1000);
        log.debug("interrupt...");
        t1.interrupt();
    }

    输出结果:

    03:47:18.141 c.Test7 [t1] - enter sleep...
    03:47:19.132 c.Test7 [main] - interrupt...
    03:47:19.132 c.Test7 [t1] - wake up...
    java.lang.InterruptedException: sleep interrupted
        at java.lang.Thread.sleep(Native Method)
        at cn.itcast.test.Test7$1.run(Test7.java:14)

  3. 睡眠结束后的线程未必会立刻得到执行

  4. 建议用 TimeUnit 的 sleep 代替 Thread 的 sleep 来获得更好的可读性 。其底层还是sleep方法。

    @Slf4j(topic = "c.Test8")
    public class Test8 {
    ​
        public static void main(String[] args) throws InterruptedException {
            log.debug("enter");
            TimeUnit.SECONDS.sleep(1);
            log.debug("end");
    //        Thread.sleep(1000);
        }
    }

  5. 在循环访问锁的过程中,可以加入sleep让线程阻塞时间,防止大量占用cpu资源。

yield

  1. 调用 yield 会让当前线程从 Running 进入 Runnable 就绪状态,然后调度执行其它线程

  2. 具体的实现依赖于操作系统的任务调度器

线程优先级

  • 线程优先级会提示(hint)调度器优先调度该线程,但它仅仅是一个提示,调度器可以忽略它

  • 如果 cpu 比较忙,那么优先级高的线程会获得更多的时间片,但 cpu 闲时,优先级几乎没作用

测试优先级和yield

@Slf4j(topic = "c.TestYield")
public class TestYield {
    public static void main(String[] args) {
        Runnable task1 = () -> {
            int count = 0;
            for (;;) {
                System.out.println("---->1 " + count++);
            }
        };
        Runnable task2 = () -> {
            int count = 0;
            for (;;) {
//                Thread.yield();
                System.out.println("              ---->2 " + count++);
            }
        };
        Thread t1 = new Thread(task1, "t1");
        Thread t2 = new Thread(task2, "t2");
        t1.setPriority(Thread.MIN_PRIORITY);
        t2.setPriority(Thread.MAX_PRIORITY);
        t1.start();
        t2.start();
    }
}

测试结果:

#优先级
---->1 283500
---->2 374389
#yield
---->1 119199
---->2 101074

可以看出,线程优先级和yield会对线程获取cpu时间片产生一定影响,但不会影响太大。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

向着五星的方向

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值