yield和sleep 以及yield如何使用

yield()是什么?在什么场景下使用? 在多线程开发中经常用到的sleep跟这个没怎么见过的yield有什么联系呢

public static void sleep(long millis) throws InterruptedException

Causes the currently executing thread to sleep (temporarily cease execution) for the specified number of milliseconds, subject to the precision and accuracy of system timers and schedulers.

让当前线程睡眠(暂时停止执行)指定的毫秒数,服从系统定时器和调度器的精度和准度。

public static void yield()

A hint to the scheduler that the current thread is willing to yield its current use of a processor. The scheduler is free to ignore this hint.

提醒调度器“这个线程愿意让出线程所占用的处理器(处理器理解为硬件线程)”

以上就是这个主题下很多文章会讲的东西,就只是文档上写的,比较难懂,我来换一个思路,以Java为例。
如果有错误,欢迎指正。

线程睡眠是让线程暂停执行,占用的处理器会被操作系统回收去执行别的线程,在时间过去后恢复执行(服从调度)。
这里并不需要担心睡眠之后没有处理器来执行睡眠的线程,因为操作系统会给每个执行的线程计时,指定的时间用完就会让处理器暂停当前线程,安排另外一个线程。(关键词:时间片timeslice)

yield是主动释放处理器。

注意到共同点了吗?它们都会让出处理器。
yield()执行期间线程自己的代码无法继续,而很可能会有别的线程执行。

那么yield就可以用来实现一个简单的sleep。
我们直接循环释放处理器,循环条件设为时间,再加上中断异常。
请不要真的这么做,这个实现比用空循环实现占用低,但是比真正的sleep要差很多!
而且yield并不一定会释放处理器!

public class MySleep {
    public static void sleep(long millis) throws InterruptedException {
        long start = System.currentTimeMillis();
        do {
            Thread.yield();
            if (Thread.interrupted()) {
                throw new InterruptedException();
            }
        } while (System.currentTimeMillis() - start < millis);
    }
}

请注意不要把这里的do-while当成标准,即使确实存在某个语言在某个平台上的某个库里的sleep(0);会直接yield();
但这并不代表全部的实现都会是这样!即使现在是也不代表未来更新不会修改

同理,线程join
既然很有可能yield期间会有别的线程执行,那么这之后也有可能一个线程执行完了

public class MyJoin {
    public static void join(Thread t) throws InterruptedException {
        while (t.getState() != Thread.State.TERMINATED) {
            Thread.yield();
            if (Thread.interrupted()) {
                throw new InterruptedException();
            }
        }
    }
    public static void main(String[] args) {
        Thread thread = new Thread(()-> {
            try {
                Thread.sleep(2000);
            } catch (Exception e) {
            }
        });
        thread.start();
        System.out.println("before");
        try {
            join(thread);
        } catch (Exception e) {
        }
        System.out.println("after");
    }
}

再次强调
请不要真的这么做

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值