public class volatileNotEnsureAtomic {
volatile int i = 0;
/**
* 由于volatile虽然支持可见性,支持单个变量的读写原子性,但不支持复合操作的原子性
*
*/
public void method() {
i++;
}
public static void main(String[] args) {
volatileNotEnsureAtomic vo = new volatileNotEnsureAtomic();
for(int j = 0; j<5;j++) {
new Thread() {
@Override
public void run() {
for(int k = 0;k<1000;k++) {
vo.method();
}
System.out.println("子线程执行");
};
}.start();
}
while(Thread.activeCount() > 2) {//线程有一个守护线程
Thread.yield();
}
System.out.println("主线程执行");
System.out.println(vo.i);
}
}
运行结果:
子线程执行
子线程执行
子线程执行
子线程执行
子线程执行
主线程执行
4456
知识点:
1、volatile关键字保证单个变量的原子性,但是不能保证复合操作如++的原子性
2、运行结果会出现主线程执行-->子线程执行的结果:
yields:使当前线程从执行状态(运行状态)变为可执行态(就绪状态)。cpu会从众多的可执行态里选择,也就是说,当前也就是刚刚的那个线程还是有可能会被再次执行到的,并不是说一定会执行其他线程而该线程在下一次中不会执行到了。
所有可执行的线程开始重新获取cpu时间,优先级高的线程只是获取cpu时间的概率比较高,但是并不意味着优先级低的线程就无法抢到cpu执行时间