细读jsr中的yield语义,或者不是我们想象中的那样
这只是我的个人观点,如有错误,希望你可以指出。
首先英文原版
中文译版
我觉得“不需要”还会让人产生误解,应该译为不一定要。
很多时候会被断章取义地理解,我们一定要有“不一定”,“可能”的意识,下面给出一段代码演示,亲测。
static boolean close=false; public static void main(String[] args) throws InterruptedException {
new Thread(()->{ //且称线程1
int count=1;
while(!close){
Thread.yield(); //sleep()有同样的效果
count++;
}
System.out.println("yield"+count);//等待io
}).start(); Thread.sleep(100);
close=true;
} //yield77616,这个数在70000-110000左右
线程是会停止的,这时候断章取义者就会百思不得其解。
那么jsr中的又是什么意思呢?
是基于这样的一个假设的:
主线程在cpu0上运行。
线程1一直在cpu1上运行,虽然线程1 yield,但是没有别的线程来使用cpu1,意思为cpu1中寄存器,缓存中存着的还是线程1的数据,如变量close。
然而,如果在线程1 yield或者sleep的时候,操作系统调度别的线程来使用cpu1,那么cpu1中存放的旧数据将会刷回主存(实际刷回时机视实际情况,不同的cpu应该会有不同的策略),然后存放别的线程所需的数据。那么等到线程1 yield或者sleep完毕,到它使用cpu1(不一定是cpu1)的时候,发现没有命中缓存,就会从主存中把变量close读取进来,而这个时候主存当中的close已经被主线程修改为true了,因此循环结束。
而实际情况是,时时刻刻都有大量的线程在工作,你放弃了就会有别人来用。
所以它真正强调的意思是“不主动”,而像volatile就会主动去做某些措施。
继续补充
static boolean close=false; public static void main(String[] args) throws InterruptedException {
new Thread(()->{
//int count=1;
while(!close){
System.out.println("io操作");
}
System.out.println("io操作完毕");
}).start(); Thread.sleep(100);
close=true;
}
// io操作
// io操作
// .
// .
// .
// io操作
// io操作完毕
如上,线程1在进行IO操作的时候,将会有别的线程来使用cpu1,线程1照样结束循环。
只有这样才不会结束
while(!close){
}
总结
一言以蔽之,只要cpu没有命中缓存,就会从主存中读取。
再补充
可能会觉得,那这样的话,yield和sleep就像是普通的正常的操作(反正肯定会有别的线程来使用cpu)啊,有必要这样强调吗?
我觉得
一是文档的规范性,完整性。
二,也是曾在“为什么java的称为虚拟机,而python的称为解释器”这样的问题中,看到的一个答案。(不保证正确)
jvm是模仿着硬件去设计的,像一些操作,取操作码,取操作数,push,store等指令。如果按照jvm去配置硬件,有可能做到cpu中就只有jvm的线程在跑,或者说通俗点说jvm就是操作系统。那这样的话,就真的满足之前的假设了——“线程1一直在cpu1上运行,虽然线程1 yield,但是没有别的线程来使用cpu1”。
细读jsr中的yield语义,或者不是我们想象中的那样的更多相关文章
- Python3中的yield from语法
Python3中的yield from语法 by Kay Zheng Tags: python, 协程, generator 30 March 2014 2016-2-23 更新 這篇文章是兩年前寫的 ...
- 可惜Java中没有yield return
项目中一个消息推送需求,推送的用户数几百万,用户清单很简单就是一个txt文件,是由hadoop计算出来的.格式大概如下: uid caller 123456 12345678901 789101 12 ...
- 初次使用C#中的yield
这几天在Python程序员的微信订阅号中总是见到yield的关键字,才想起来在C#中也是有yield,但是只是知道有,从来没有了解过他的用法,今天有时间就来看看是怎么使用的.刚开始肯定就是搜索一下用法 ...
- C#中的yield return与Unity中的Coroutine(协程)(上)
C#中的yield return C#语法中有个特别的关键字yield, 它是干什么用的呢? 来看看专业的解释: yield 是在迭代器块中用于向枚举数对象提供值或发出迭代结束信号.它的形式为下列之一 ...
- 关于Python中的yield
关于Python中的yield 在介绍yield前有必要先说明下Python中的迭代器(iterator)和生成器(constructor). 一.迭代器(iterator) 在Python中,f ...
- 关于Python中的yield(转载)
您可能听说过,带有 yield 的函数在 Python 中被称之为 generator(生成器),何谓 generator ? 我们先抛开 generator,以一个常见的编程题目来展示 yield ...
- C#中的yield return用法演示源码
下边代码段是关于C#中的yield return用法演示的代码. using System;using System.Collections;using System.Collections.Gene ...
- python 中的 yield 究竟为何物?生成器和迭代器的区别?
当你突然看到别人的代码中出现了一个好像见过但又没用过的关键词 比如 yield ,你是否会觉得这段代码真是高大上呢? 或许只有我这种小白才会这样子觉得,就在刚刚,我就看见了别人的代码中的yield,觉 ...
- Python中的yield生成器的简单介绍
Python yield 使用浅析(整理自:廖 雪峰, 软件工程师, HP 2012 年 11 月 22 日 ) 初学 Python 的开发者经常会发现很多 Python 函数中用到了 yield 关 ...
随机推荐
- Python线程-死锁
死锁产生的4个必要条件: 1.互斥:一个资源同一时刻只允许一个线程进行访问. 2.占有未释放:一个线程占有资源,且没有释放资源. 3.不可抢占:一个已经占有资源的线程无法抢占到其他线 ...
- python简易计算器
import re """ 过程:(最内部的括号->先乘除,替换->整理表达式->加减)->替换 """ def m ...
- python __init__()类构造方法
构造方法用于创建对象时使用,每当创建一个类的实例对象时,python解释器都会自动调用它. class Person: def __init__(self): print("调用构造方法&q ...
- [总结]ACM模拟总结
1.心态一定要稳,千万不要慌. 2.内部交流要多点,说不定就讨论出有用的性质了. 3.题目细节一定要想清楚. 4.一道题绝对不能让多个人来写. 5.英语要好好学.
- SpringCloud与微服务Ⅵ --- Ribbon负载均衡
一.Ribbon是什么 Sping Cloud Ribbon是基于Netflix Ribbon实现的一套客户端负载均衡的工具. 简单的说,Ribbon是Netflix发布的开源项目,主要功能是提供客户 ...
- (转)Gamma分布,Beta分布,Multinomial多项式分布,Dirichlet狄利克雷分布
1. Gamma函数 首先我们可以看一下Gamma函数的定义: Gamma的重要性质包括下面几条: 1. 递推公式: 2. 对于正整数n, 有 因此可以说Gamma函数是阶乘的推广. 3. 4. ...
- MySQL 锁的小结
摘自:https://www.cnblogs.com/protected/p/6526857.html 关于数据库的各种锁的总结: 1.共享锁(又称读锁).排它锁(又称写锁): InnoDB引擎的锁机 ...
- STL中的vector 和list
参考书目:visual c++ 入门经典 第七版 Ivor Horton著 第十章 认识两个容器:vector和list 容器:是STL(Standard Template Library 标准模板库 ...
- 娱乐往事,年初捡到1G PAR,平淡的日子泛起波澜
常听说这样的故事 垃圾佬捡到蓝牙键盘,于是配了一台上万的电脑 垃圾佬捡到机箱,于是配了一台带遥控的HTPC 垃圾佬捡到假NAS,于是组了20+T的RAID 而我,不是垃圾佬,更没有捡到过U盘,对突如其 ...
- 学习记录一(Python算数运算符与if语句)
从网上找到一个Python的学习视频,之前的环境都装好了,今天看的就是算术运算符和变量的命名 其中Python的除法直接就是 / %用于求余 其中还可以进行幂运算** 例如2 ** 3 = 8 ...