sleep 与 yield

sleep

Thread 类中有一个静态的 sleep 方法,当一个执行中的线程调用了 Thread 的 sleep 方法后,调用线程会暂时让出指定时间的执行权,也就是在这期间不参与 CPU 的调度,但是该线程所拥有的监视器资源,比如锁还是持有不让出的。指定的睡眠时间到了后该函数就会正常返回,线程就处于就绪状态,然后参与 CPU 调度,获取到 CPU 资源后就可以继续执行了

线程在睡眠时拥有的监视器资源不会释放。

public class SleepTest {
    /**
     * 创建一个独占锁
     */
    private static final Lock lock = new ReentrantLock();

    public static void main(String[] args) {
        //创建线程A
        Thread threadA = new Thread(new Runnable() {
            public void run() {
                //获取独占锁
                lock.lock();
                try {
                    System.out.println("子线程 A 睡眠中...");
                    Thread.sleep(1000);
                    System.out.println("子线程 A 苏醒...");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    //释放锁
                    lock.unlock();
                }
            }
        });

        //创建线程 B
        Thread threadB = new Thread(new Runnable() {
            public void run() {
                //获取独占锁
                lock.lock();
                try {
                    System.out.println("子线程 B 睡眠中...");
                    Thread.sleep(1000);
                    System.out.println("子线程 B 苏醒...");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    //释放锁
                    lock.unlock();
                }
            }
        });

        //启动线程
        threadA.start();
        threadB.start();
    }
}

当一个线程处于睡眠状态是,如果另外一个线程中断了它,会在调用 sleep 方法出抛出异常

public class SleepInterruptTest {

    public static void main(String[] args) throws InterruptedException {
        //创建线程
        Thread thread = new Thread(new Runnable() {
            public void run() {
                try {
                    System.out.println("子线程睡眠中...");
                    Thread.sleep(10000);
                    System.out.println("子线程苏醒...");
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });

        //启动线程
        thread.start();

        //主线程休眠2s
        Thread.sleep(2000);

        //主线程中断子线程
        thread.interrupt();
    }
}

另外需要注意的是,如果在调用 Thread.sleep(long millis) 时为 millis 参数传递了一个负数,则会抛出 IllegalArgumentException 异常。

yield

当一个线程调用 yield 方法时,当前线程会让出 CPU 的使用权,然后处于就绪状态,线程调度器会从线程就绪队列里面获取一个线程优先级最高的线程,当然也有可能会调度到刚刚让出 CPU 的那个线程来获取 CPU 的执行权。

public class YieldTest implements Runnable{

    YieldTest(){
        //创建并启动线程
        Thread t = new Thread(this);
        t.start();
    }

    public void run() {
        for (int i = 0; i < 5; i++) {
            //当 i=0 是让出 CPU 执行权,放弃时间片,并进行下一轮调度
            if (i % 5 == 0){
                System.out.println(Thread.currentThread() + "yield cpu ...");

                //当前线程让出 cpu 执行权,放弃时间片,进行下一轮调度
                Thread.yield();
            }
        }

        System.out.println(Thread.currentThread() + "is over...");
    }

    public static void main(String[] args) {
        new YieldTest();
        new YieldTest();
        new YieldTest();
    }
}

sleep与yield的区别

  • 当线程调用 sleep 方法时,调用线程会被阻塞挂起指定时间,在这期间线程调度器不会调度该线程。
  • 调用 yield 方法时,线程只会让出自己剩余的时间片,并没有被阻塞挂起,而是处于就绪状态,线程调度器下一次调度时就有可能调度到当前线程执行。
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值