一般情况不加锁在多线程下访问共享变量会出问题
例如:
public class cas {
public static void main(String[] args) {
Bank a = new Bank();
a.DeclineMoney();
}
}
class Bank {
int money = 100;
void DeclineMoney() {
for (int i = 0; i < 50; i++) {
new Thread(() -> {
while (true) {
if (money >= 1) {
try {
Thread.sleep(10); // 模拟并发问题
} catch (InterruptedException e) {
e.printStackTrace();
}
money -= 1;
System.out.println("当前剩余金额: " + money);
}
}
}).start();
}
}
}
.............
当前剩余金额: 17
当前剩余金额: 18
当前剩余金额: 20
当前剩余金额: 22
当前剩余金额: -4
当前剩余金额: -1
当前剩余金额: -3
当前剩余金额: 2
当前剩余金额: 3
当前剩余金额: 2
当前剩余金额: 3
当前剩余金额: -38
当前剩余金额: -37
当前剩余金额: 1
当前剩余金额: -36
................
余额成为负数显然有问题。
使用Synchronized就不会出现并放问题
public class cas {
public static void main(String[] args) {
Bank a = new Bank();
a.DeclineMoney();
}
}
class Bank {
int money = 100;
void DeclineMoney() {
for (int i = 0; i < 10; i++) {
new Thread(() -> {
while (true) {
synchronized (this) {
if (money >= 1) {
try {
Thread.sleep(10); // 模拟并发问题
} catch (InterruptedException e) {
e.printStackTrace();
}
money -= 1;
System.out.println("当前剩余金额: " + money);
}
}
}
}).start();
}
}
}
输出:
当前剩余金额: 18
当前剩余金额: 17
当前剩余金额: 16
当前剩余金额: 15
当前剩余金额: 14
当前剩余金额: 13
当前剩余金额: 12
当前剩余金额: 11
当前剩余金额: 10
当前剩余金额: 9
当前剩余金额: 8
当前剩余金额: 7
当前剩余金额: 6
当前剩余金额: 5
当前剩余金额: 4
当前剩余金额: 3
当前剩余金额: 2
当前剩余金额: 1
当前剩余金额: 0
利用CAS无锁解决并发问题
public class cas {
public static void main(String[] args) {
Bank a = new Bank();
a.DeclineMoney();
}
}
class Bank {
AtomicInteger money = new AtomicInteger(100);
void DeclineMoney() {
for (int i = 0; i < 100; i++) {
new Thread(() -> {
while (true) {
int prev = money.get();
int next = prev - 1;
if (money.compareAndSet(prev, next)) {
System.out.println("当前剩余金额: " + next);
break; // 成功修改后退出循环
}
// 如果 CAS 失败,继续重试
}
}).start();
}
}
}
输出
..........
当前剩余金额: 20
当前剩余金额: 19
当前剩余金额: 18
当前剩余金额: 17
当前剩余金额: 16
当前剩余金额: 15
当前剩余金额: 14
当前剩余金额: 13
当前剩余金额: 12
当前剩余金额: 11
当前剩余金额: 10
当前剩余金额: 9
当前剩余金额: 8
当前剩余金额: 7
当前剩余金额: 4
当前剩余金额: 5
当前剩余金额: 3
当前剩余金额: 6
当前剩余金额: 1
当前剩余金额: 2
当前剩余金额: 0