java线程问题,直接看代码吧。不好描述。
Foo类实现了Runnable接口
public class Foo implements Runnable{
private boolean isRun ;
@Override
public void run() {
isRun = true;
while (isRun){
System.out.println("runing ......");
}
}
public void stop(){
this.isRun = false;
}
@Override
public String toString() {
return "Foo{" +
"isRun=" + isRun +
'}';
}
}
测试类
public class ThreadTest {
public static void main(String[] args) {
Foo f = new Foo();
Thread t = new Thread(f);
t.start();
f.stop();
System.out.print(f);
}
}
为什么执行了stop()方法之后,t线程没有停止执行呢。
我debug发现thread在运行start()方法之前,里面的Foo对象和执行stop()方法的Foo对象是同一个。按理说执行stop()方法后。f的isRun被设置成了false,线程读取到该变量变成false应该停止才对。
看thread的源码
求大神解答。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
而且
isRun
一直是true
, 你应该改成:isRun
一开始就初始化,应该这么写:最终输出:
这应该是一个老问题了. 我没做实验, 但按我的理解,
private volatile boolean isRun;
可以解决你的问题.这里涉及到一个java hotspot 过度优化的问题,
这里
while(isRun){...}
会被JIT翻译为 本地代码. 因为没有volatile
, 很大可能直接翻译为while
. 有兴趣去 找一个java fastdebug 版本, 看看jit翻译后的汇编码, 这个我以前弄过.(true){...}
至于@netingcn 同学的解决方案, 这里while不会成为热点代码, 所以不会做优化.
以上只是以前的一点经验, 也许不完全正确.
t.start(); 并不是离开执行run方法,而是交给OS去调度。
针对你这个例子,执行的顺序是 f.stop() --> System.out.print(f) 也及时调用f对象的toString, 然后才开始线程执行。而在你的run方法中又设置 isRun = true; 所以线程无法停止。
修改Foo 如下:
这个时候你会看到类似这样的输出
说明 stop 确实在 run 之前先执行