5.Java线程中的重要方法(sleep、yield、优先级)

sleep(long millis)

  • 使当前正在执行的线程在指定的毫秒数内休眠(暂时停止执行),具体取决于系统计时器和计划程序的精度和准确性。线程只是放弃时间片,而不会失去任何监视器的所有权。也就是不会释放当前持有的锁
  • 调用sleep()会让当前线程从RUNNING进入TIMED_WAITING状态(有时限的等待);
  • 这里的Running状态是从操作系统的层面讲的,java中对应的是Runnable状态。
public static void main(String[] args) throws InterruptedException {

        Thread t1 = new Thread(new Runnable() {
            @Override
            public void run() {
                log.debug("sleeping...");
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        });

        // NEW
        log.debug("t1线程的状态 {}",t1.getState());

        t1.start();

        // RUNNABLE
        log.debug("t1线程的状态 {}",t1.getState());

        Thread.sleep(500);
        // TIMED_WAITING
        log.debug("t1线程的状态 {}",t1.getState());
    }
  • 正在睡眠的线程可以被其他线程被打断。使用interrupt()方法打断。被打断时会抛出InterruptedException。
  • 睡眠结束的线程未必会立刻得到执行。需要等到调度器重新分配时间片后才能执行
  • 建议使用TimeUnit的sleep代替Thread的sleep方法,来获得更好的可读性
TimeUnit.SECONDS.sleep(5);

yield()

  • 提示调度器,当前线程愿意让出处理器的使用权,当然,调度器可以忽略这个提示。具体的实现依赖于操作系统的调度器

  • Yield(让步)是一种启发式尝试,旨在改善线程之间的相对进展,以避免线程过度使用 CPU

  • 调用yield方法会让当前线程从Running状态进入Runnable状态

优先级

  • 线程的优先级会提示调度器,优先调用该线程,但仅仅是一个提示,调度器可以忽略这个提示;
  • CPU忙时,更高优先级的线程会获得更多的时间片,但是CPU空闲时,优先级几乎没什么用。

yield和优先级的例子

  • 开启两个线程,这两个线程做的事情一样,在死循环中从0开始打印。

  • 不加其他任何条件的话,两个线程应该是差不多的进度:

    public static void main(String[] args) throws InterruptedException {

        Thread t1 = new Thread(new Runnable() {
            @Override
            public void run() {
                int count = 0;
                while (true){
                    log.debug("t1-count: {}",count++);
                }

            }
        },"t1");

        Thread t2 = new Thread(new Runnable() {
            @Override
            public void run() {
                int count = 0;
                while (true){
                    log.debug("t2-count: {}",count++);
                }

            }
        },"t2");

        t1.start();
        t2.start();

    }

输出:

2025-10-03 10:59:30.640 [t2] c.c.e.d.Main - t2-count: 133931
2025-10-03 10:59:30.640 [t2] c.c.e.d.Main - t2-count: 133932
2025-10-03 10:59:30.640 [t2] c.c.e.d.Main - t2-count: 133933
2025-10-03 10:59:30.640 [t1] c.c.e.d.Main - t1-count: 132667
2025-10-03 10:59:30.640 [t1] c.c.e.d.Main - t1-count: 132668
2025-10-03 10:59:30.640 [t1] c.c.e.d.Main - t1-count: 132669
2025-10-03 10:59:30.640 [t1] c.c.e.d.Main - t1-count: 132670
  • 增加条件:t2线程在打印之前,执行yield方法。那么t1的进度就应该比t2大
    public static void main(String[] args) throws InterruptedException {

        Thread t1 = new Thread(new Runnable() {
            @Override
            public void run() {
                int count = 0;
                while (true){
                    log.debug("t1-count: {}",count++);
                }
            }
        },"t1");

        Thread t2 = new Thread(new Runnable() {
            @Override
            public void run() {
                int count = 0;
                while (true){
                    Thread.yield();
                    log.debug("t2-count: {}",count++);
                }
            }
        },"t2");

        t1.start();
        t2.start();

    }

输出:

2025-10-03 11:01:54.349 [t2] c.c.e.d.Main - t2-count: 62626
2025-10-03 11:01:54.349 [t2] c.c.e.d.Main - t2-count: 62627
2025-10-03 11:01:54.349 [t1] c.c.e.d.Main - t1-count: 155354
2025-10-03 11:01:54.349 [t2] c.c.e.d.Main - t2-count: 62628
  • 增加条件,不执行yield,而是设置它们的优先级,t1高优先级,t2低优先级。t1的进度就应该比t2大
    public static void main(String[] args) throws InterruptedException {

        Thread t1 = new Thread(new Runnable() {
            @Override
            public void run() {
                int count = 0;
                while (true){
                    log.debug("t1-count: {}",count++);
                }
            }
        },"t1");

        Thread t2 = new Thread(new Runnable() {
            @Override
            public void run() {
                int count = 0;
                while (true){
                    log.debug("t2-count: {}",count++);
                }
            }
        },"t2");

        t1.setPriority(Thread.MAX_PRIORITY);
        t2.setPriority(Thread.MIN_PRIORITY);

        t1.start();
        t2.start();

    }

输出:

2025-10-03 11:04:28.068 [t2] c.c.e.d.Main - t2-count: 149533
2025-10-03 11:04:28.068 [t2] c.c.e.d.Main - t2-count: 149534
2025-10-03 11:04:28.068 [t1] c.c.e.d.Main - t1-count: 175607

sleep方法的应用

当程序中使用while(true)时,可以使用sleep(),来防止CPU空转。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值