关于java多线程的一个问题

Chancy_cx 2017-10-31 03:00:26
做一个多线程的题目
实现
*g
*g*g
*g*g*g
.......
实现其实不难,不过中间我遇到一个地方一直很难理解。上代码


上测试图


就是很奇怪,为什么副线程执行一遍过后就无法执行了,只有加了sleep那段语句才能成功。
测试了一晚了没找到问题,可能哪些地方我还没学到?想请教一下各位大神。
...全文
295 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
yql1986 2017-10-31
  • 打赏
  • 举报
回复
我回答一下: 线程的执行具有不确定性的。不能按照程序应该顺序执行的思路。 看你的ToDo类的 main方法中,在执行到for循环的时候之前已经开启了一个线程,理所当然的认为线程应该已经执行了。按照程序顺序执行的思路,开启线程的代码在前,for循环的代码在后,实际上当for循环执行的时候,线程还一定开始执行了,线程执行要等待操作系统分配相应的资源,如果执行for循环的时候,没有操作系统分配相应的资源,线程就不会执行。 所以按照这样的思路,当在for循环中将控制变量flag设置为true时,理所当然认为线程判断该flag变量为true后应该会执行,因为线程具有不确定性,因为在设置true的时候,你能确定线程正在执行哪一行代码,可能在你设置true的时候,它已经执行了好几次循环了,也可能它的资源被操作系统收回,停顿了。 所以你后面用try{Thread.sleep(0)}的时候,当线程被操作系统唤醒的时候,恰巧读取了变量flag=true 还有一点你要了解一下,JAVA内存模型,JAVA有它自己的内存模型,JVM规范定义了JAVA怎样进行内存同步。 Run类中的flag变量应该用volatitle,main中设置了flag=true,Run类线程实例读取的变量flag不一定true,了解一下volatitle 关键字
pilnyun335857183 2017-10-31
  • 打赏
  • 举报
回复
这是jit编译优化的问题,jit会将循环中使用到的变量直接从工作内存中读取,所以myThread线程中flag一直会是false。而添加sleep0后让出了cpu时间,实际是jmm的机制会起作用;jmm规范中会尽量保证变量在主内存和各个工作内存之间的同步但是必须要有机会执行同步机制才行,sleep0就起到这个作用。可以去了解jmm及jit。 要保证flag变量的同步,可以加上volatile关键字就好。话说你ToDo中不是有个加了volatile的flag吗?为什么不用那个?
scortic 2017-10-31
  • 打赏
  • 举报
回复
不太确定吧. 没有加Thread.sleep0(); 当执行完之后,该线程就关闭了,一条关闭的线程应该是不能再启动的吧. 当加了Thread.sleep(0); 执行完之后,当前线程进入了阻塞状态,将处理器的时间片释放出来,当后面再调用start方法的时候,其实方法内调用了run方法,启动了该线程,所以该线程能继续执行... 这是我的思路,应该是这样吧! 后面的大神, 我要是理解错了不要喷...
青年卫大师 2017-10-31
  • 打赏
  • 举报
回复
线程跑太快了 flag 在两个线程中不一致 可以把 flag 加锁

51,410

社区成员

发帖
与我相关
我的任务
社区描述
Java相关技术讨论
javaspring bootspring cloud 技术论坛(原bbs)
社区管理员
  • Java相关社区
  • 小虚竹
  • 谙忆
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧