java 线程问题?

public class ThreadTest {public static void main(String[] args){System.out.println("11111");SubThread st=new SubThread();st.start();while(st.getFlag()){}System.out.println("22222");}
}public class SubThread extends Thread{private  boolean flag=true;public  boolean  getFlag(){return flag;}public void run(){try {sleep(3000);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}flag=false;}}

这样的话 22222永远输不出来, 但在 getFlag()上加上 synchronized就可以了。
还有一种就是不加 synchronized 但在while() 循环中加上一点输出(简单的操作),又可以输出了, 谁能详细解释下吗?

计算机科学等 7 个话题下的优秀答主

15 人赞同了该回答

从另一个问题传送过来 如何查看Java代码的汇编形式? - 计算机
题主的问题在这帖里有详细解释:有没有什么工具可以查看正在运行的类的c/汇编代码

Android 开发话题下的优秀答主

看看你的JVM把这一段编译出的虚拟机指令是什么就知道了

发现更大的世界

9 人赞同了该回答

被优化掉了,getFlag只读一次到寄存器,然后就不会再读了。

另外,signal最好别这么写……一般都会有专门的spinLock或者semaphore可以用。

(学好编译原理和操作系统就不会问这个问题了,所以你们看,所谓三大浪漫不是没用的……)

需要把flag变量声明为volatile,保证flag变量永远位于内存中,否则jvm可能会缓存flag到寄存器

出现这种问题可能是主线程在使用subThread实例的时候将subTread实例包括flag变量的值copy了一份到主线程的栈中缓存起来,之后Main线程中访问subThread的时候会从缓存中读取flag的值。而subThread中改变flag的值并没有改变Main线程中缓存的值,因此导致死循环。
当然同样的代码我在我电脑上运行是不会产生死循环,可能跟jvm版本和启动参数有关。

可以尝试给flag变量添加volatile关键字让每次访问该变量时都从主存中同步一下该变量的最新值。看看能不能解决问题。

也可能Main线程while(true)中没有io操作,导致volatile线程一直没有被调度,所以flag一直没有被设置

发布于 2015-01-11

​赞同 4​​1 条评论

​分享

​收藏​喜欢

继续浏览内容

心有所想,但有所为。个人公众号:think123

5 人赞同了该回答

你这里相当于有两个线程了,多次执行结果肯定不一致,你出现这样的情况很明显是主线程抢到了优先权,先执行,所以得到的
Flag就为true了,就一直执行死循环了,当子线程抢到执行权的时候改变了状态又没有通知主线程,所以会出现这种情况,当然你也可以理解这个变量放到了主线程的栈中,没有及时更新,所以你要做的就是通知它就可以了

发布于 2015-01-12

​赞同 5​​添加评论

​分享

​收藏​喜欢

heshan

life is short

1 人赞同了该回答

while那句被优化成
if(st.getFlag)

while(true)

建议你看一下 effective java,里面有一节专门讲这个

典型的JMM可见性问题,使用final或者vilotile或者synchronize都可以解决问题。

但是不好测试,即使你每次运行的结果都是正确的也不代表代码是正确的。这个可以参考R大大的回复看运行时的汇编。

发布于 2015-01-18

volatile 保证可见性,了解一下

https://www.zhihu.com/question/27500017

学习编译原理对下面这段java跳不出死循环大概能有较好的解释吧相关推荐

  1. 每天两小时学习编译原理——一个学期的第三天,希望能坚持长久✨

    上一篇:每天两小时学习编译原理--一个学期的第二天,希望能坚持长久✨ 下一篇:每天两小时学习编译原理--一个学期的第四天,希望能坚持长久✨ 继续学习 编译程序过程 词法分析 语法分析 语义分析与中间代 ...

  2. 对学习编译原理的看法

    我认为编译原理这本书是一门与代码做斗争的课程,学习编译原理能够追寻程序设计语言的本质,了解计算机各种语言编译的原理.学习了编译原理能够更加深入的了解计算机各种高级语言使用的原理,能使自己更加容易更加好 ...

  3. java实验文法报告_西安邮电大学编译原理LL文法分析器实验(java).doc

    西安邮电大学编译原理LL文法分析器实验(java) <编译原理>实验报告 题目: 语法分析器的制作 学生姓名: 班 级: 软件1202 学 号: 指导教师: 成 绩: 西安邮电大学计算机学 ...

  4. 【编译原理】语言认知之Java、Python、C++快速排序三者运行效率与开发效率比较

    [编译原理]语言认知之Java.Python.C++快速排序&三者运行效率与开发效率比较 一.实验目的 二.实验环境 三.实验步骤 四.快速排序程序 五.实验结果 六.总结 一.实验目的 强化 ...

  5. 【编译原理】课程实验——基于Java的词法分析与语法分析

    ⭐⭐⭐⭐⭐⭐ Github主页

  6. 学了编译原理能否用 Java 写一个编译器或解释器?

    16 个回答 默认排序​ RednaxelaFX JavaScript.编译原理.编程 等 7 个话题的优秀回答者 282 人赞同了该回答 能.我一开始学编译原理的时候就是用Java写了好多小编译器和 ...

  7. 编译原理学习笔记一(待续)

    这几天忙着学英语,同时在学习编译原理,对这门课很感兴趣,已经制作了词法分析器,同时还在补充这个分析器的功能,也准备着手开始写语法分析器,看到最后能不能连在一起,我想如果能够将整套编译器的流程跑下来真的 ...

  8. [编译原理学习]词法分析

    此前一直没能系统完整地学过编译原理,只有很粗浅的理解,虽然其实对工作里的任务也没啥影响,但总觉得缺了一大块知识,加上对所谓程序员三大浪漫(编译器,操作系统,图形学)的向往,所以最近跟着网易云课堂推出的 ...

  9. 计算机编译原理有必要学吗,计算机程序编译原理学习心得

    计算机程序编译原理学习心得 <编译原理>是计算机专业的一门重要课程,正如教材:第一章的引论所述,"编译程序是现代计算机系统的基本组成部分之一"."一个编译程序 ...

最新文章

  1. 搭载M1芯片的MacBook能不能当开发主力机?程序员半个月的亲身体验都在这里
  2. 零基础可以学python吗-学Python需要什么基础知识?零基础可以学Python吗?
  3. mysql插入ㄖ_原生JavaScript代码100个实例
  4. Git环境搭建与基本使用方法 (转自http://blog.csdn.net/fireelement/article/details/9618363)
  5. 2个css特效冲突了怎么办_患上类风湿病怎么办?2个方法拿走不谢
  6. Opencv dnn实现人类性别检测和年龄预测
  7. JDK时区与电脑系统时区不一致,导致时间new date不对
  8. linux驱动之可加载模块
  9. 计算机学win7画图,win7自带画图工具
  10. 现代控制理论——状态、状态空间、状态空间描述
  11. java矩阵连乘动态规划_动态规划之矩阵连乘
  12. Layui的下拉框样式失效问题
  13. 恢复计算机注册表命令,恢复电脑注册表的方法
  14. ktv点歌系统主界面java_欢迎进入MyKTV前后台点歌系统展示
  15. 零基础学kubernetes(k8s)必看教程,带你10分钟快速实战入门k8s
  16. 色彩原理:三原色、色彩三要素、色彩模型
  17. qemu 内核调试环境搭建
  18. python13:绩点计算
  19. 【渝粤题库】国家开放大学2021春2412基础写作题目
  20. 贷款报单管理系统开发-集贷前审核、贷中管理、贷后催款、逾期预警等多位于一体

热门文章

  1. python用动态规划求最短路径_动态规划之最短路径和
  2. php正则邮箱验证,php正则表达式验证(邮件地址、Url地址、电话号码、邮政编码)...
  3. 云端服务器如何调整分机显示,云电话总机分机设置_Enjoytalk云通信
  4. 裸设备 linux,Linux平台下裸设备的绑定:
  5. vue router name命名规范_超完整的Vue入门指导
  6. python打印浮点数_python – 打印整数或带有n位小数的浮点数
  7. php网页添加图片的代码,天天查询-PHP版的kindeditor编辑器加图片上传水印功能
  8. java启动无线网络连接_在无线模式存在的情况下,如何连接无线网络
  9. Service Fabric独立集群搭建
  10. ASP.NET 2.0实现自带TreeView的客户端连带选择