以下代码总结了应用程序,应用程序被随机锁定在
中while(flag)
在我的机器上运行的这段代码被抓住,在另一台机器上他正常完成
此处生成的输出是:
INIT
END
before while
before flag
after flag
代码:
package threads;
public class Run implements Runnable {
private Thread thread;
private boolean flag = true;
public void init() {
thread = new Thread(this);
thread.setName("MyThread");
thread.start();
}
@Override
public void run() {
try {
int i = 0;
while (i < 1000) {
i++;
}
System.out.println("before flag");
flag = false;
System.out.println("after flag");
} catch (Exception e) {
e.printStackTrace();
} finally {
flag = false;
}
}
public void end() {
thread.interrupt();
thread = null;
System.out.println("before while");
while (flag) {
// try { Thread.sleep(100);} catch (InterruptedException e) {}
}
;
System.out.println("after while");
}
public static void main(String[] args) {
Run r = new Run();
System.out.println("INIT");
r.init();
System.out.println("END");
r.end();
}
}
为什么当我更改标志的值时主线程没有通过循环?
答案 0 :(得分:1)
更改
private boolean flag = true;
到
private volatile boolean flag = true;
如果没有volatile
,则无法保证等待线程需要查看值更新。如果循环播放足够的时间,HotSpot甚至可以将while(flag)
内联到while(true)
。
此外,您正在做的事情称为spinlock。通常您应该使用thread.join()
代替。自旋锁是浪费资源的,因为等待线程实际上正在工作(检查变量)它应该等待的整个时间。