原子性指的是一个的操作或者多次操作,要么所有的操作全部都得到执行并且不会收到任何因素的干扰而中断,要么所有的操作都执行,要么都不执行。
synchronized 可以保证代码片段的原子性。
synchronized相比于volatile在保证可见性的同时,也保证了原子性
2个线程对变量i进行递增操作
public class LockDemo2 {
volatile int i = 0;
public void add() {
i++;
}
public static void main(String[] args) throws InterruptedException {
LockDemo2 ld = new LockDemo2();
for (int i = 0; i < 2; i++) {
new Thread(() -> {
for (int j = 0; j < 10000; j++) {
ld.add();
}
}).start();
}
Thread.sleep(2000L);
System.out.println(ld.i);
}
}
上面代码再运行的时候,volatile关键字保证了可见性,但是没有保证操作变量i的原子性,结果会出现20000以外的错误结果。
public class LockDemo2 {
int i = 0;
public void add() {
synchronized (this) {
i++;
}
}
public static void main(String[] args) throws InterruptedException {
LockDemo2 ld = new LockDemo2();
for (int i = 0; i < 2; i++) {
new Thread(() -> {
for (int j = 0; j < 10000; j++) {
ld.add();
}
}).start();
}
Thread.sleep(2000L);
System.out.println(ld.i);
}
}
synchronized同步代码块在保证了可见性的同时,也保证了变量i的原子性,当自己线程在使用i变量时,其他线程都不能对变量i进行操作。
原文:https://www.cnblogs.com/shuzhixia/p/13335981.html