volatile 关键字,使一个变量在多个线程间可见
- mian,t1线程都用到一个变量,java默认是T1线程中保留一份副本,这样如果main线程修改了该变量,
- t1线程未必知道
- 使用volatile关键字,会让所有线程都会读到变量的修改值
volatile不能保证原子性举例
比如说第一个线程加到100了,还没往上加,另外一个线程来了,把100拿过来执行方法,
- 然后第一个线程继续加到101,第二个线程也加到101,他两往回写都是101,线程不会管你加到哪儿了,
- 虽然说加了2但是实际上只加了1.
- volatile并不能保证多个线程共同修改running变量时所带来的不一致问题,
- 也就是说volatile不能替代synchronized或者说volatile保证不了原子性
public class Demo {
volatile int count = 0;
public void test(){
for (int i = 0; i < 10000; i++) {
count ++;
}
}
public static void main(String[] args) {
Demo demo = new Demo();
List<Thread> threads = new ArrayList<>();
for (int i = 0; i < 10; i++) {
threads.add(new Thread(demo::test, "thread-" + i));
}
threads.forEach((o)->o.start());
threads.forEach((o)->{
try {
o.join();
} catch (Exception e) {
e.printStackTrace();
}
});
System.out.println(demo.count);
}
}
public class Demo {
int count = 0;
//相比较上一个例子,synchronized既保证了原子性又保证了可见性
public synchronized void test(){
for (int i = 0; i < 10000; i++) {
count ++;
}
}
public static void main(String[] args) {
Demo demo = new Demo();
List<Thread> threads = new ArrayList<Thread>();
for (int i = 0; i < 10; i++) {
threads.add(new Thread(demo::test, "thread-" + i));
}
threads.forEach((o)->o.start());
threads.forEach((o)->{
try {
o.join();
} catch (Exception e) {
e.printStackTrace();
}
});
System.out.println(demo.count);
}
}
来源:CSDN
作者:阳光zfc
链接:https://blog.csdn.net/qq_27584277/article/details/103881071