volatile特性
- 保证线程可见性 MESI缓存一致性协议
- 禁止指令重排序
volatile线程可见性,但不能保证操作原子性
import java.util.ArrayList;
import java.util.List;
public class TestVolatileNotSync {
volatile int count = 0;
void m() {
for(int i=0; i<10000; i++) count++;
}
public static void main(String[] args) {
TestVolatileNotSync t = new TestVolatileNotSync();
List<Thread> threads = new ArrayList<Thread>();
for(int i=0; i<10; i++) {
threads.add(new Thread(t::m, "thread-"+i));
}
threads.forEach(Thread::start);
threads.forEach((o)->{
try {
o.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
});
System.out.println(t.count);
}
}
输入结果:58155
多次运行到达不了100000,volatile并不能保证多个线程共同修改i变量时所带来的不一致问题,也就是说volatile不能替代synchronized。
import java.util.ArrayList;
import java.util.List;
public class TestVolatileSync {
/*volatile*/ int count = 0;
synchronized void m() {
for (int i = 0; i < 10000; i++)
count++;
}
public static void main(String[] args) {
TestVolatileSync t = new TestVolatileSync();
List<Thread> threads = new ArrayList<Thread>();
for (int i = 0; i < 10; i++) {
threads.add(new Thread(t::m, "thread-" + i));
}
threads.forEach((o) -> o.start());
threads.forEach((o) -> {
try {
o.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
});
System.out.println(t.count);
}
}
输入结果:100000
网友评论