最近在编写项目的时候使用while遇到了一个奇怪的问题。我在使用异步调用的时候主线程某一个方法须要等待异步返回才能被调用,所以我设定了一个boolean,当异步返回时修改条件而后在主线程的方法中加入while来长时间遍历以等待异步返回。java
这里我将代码省略只保留主要:异步
public static void main(String[] args) {
Task task = new Task();
new Thread(task).start();
try {
Thread.sleep(3000);
} catch (Exception e) {}
task.close();
}
class Task implements Runnable {
private int i = 1;
public void run() {
while (i == 1){}
System.out.println("跳出循环");
}
public void close() {
i = 2;
}
}
复制代码
Task启动后会在while中死循环,主线程等待3s后将i修改为2,可是task中的while没有跳出,即 i == 1 条件仍是为true。spa
其中的while换成for,do-while都是同样的结果线程
经过询问他人,虽然没有弄明白发生的缘由。可是他提出了一个解决办法。code
在程序中内存
while(i == 1){}
复制代码
会过多占用CPU,所以使用Thread.yield()来将CPU资源让步给其余线程。当while中加入这个以后就能达到我须要的效果了。资源
更新: Java内存模型规定:同步
这三点直接就点名了错误的缘由。解决办法有两个:string
volatile关键字:
volatile语意:it
缺点:volatile只能保证线程的变量可见性。可是它没有锁机制,因此没法避免多个线程同时访问公共变量。
优势:编写简单。
synchronized关键字
synchronized语意:
优势:有加锁机制,保护共享资源。
Java内存协议规定了8中原子操做:
这些操做都是原子性,可是操做之间不是原子性。