多线程的同步问题
程序员文章站
2022-05-02 12:05:36
...
看一个例子,背景是,银行卡里有1000块钱,在柜台取800块钱,在提款机取800块钱,理论上来说,这个是不允许的
看看实现代码
package test;
public class FetchMoney {
public static void main(String[] args) {
Bank bank = new Bank();
MoneyThread thread1 = new MoneyThread(bank); // 柜台手续线程
MoneyThread thread2 = new MoneyThread(bank); // 自助机手续线程
thread1.start();
thread2.start();
}
}
class Bank {
private int money = 1000;
public int getMoney(int money) {
if(money < 0) {
return -1;
}
if(money > this.money) {
return -2;
}
try {
Thread.sleep(1000); // 取钱前的一些准备工作
} catch (Exception e) {
e.printStackTrace();
}
this.money -= money;
return money;
}
}
class MoneyThread extends Thread {
private Bank bank;
public MoneyThread(Bank bank) {
this.bank = bank;
}
@Override
public void run() {
System.out.println(bank.getMoney(800));
}
}
执行的结果是
800
800
Process finished with exit code 0
1000块钱的余额居然真的取出2次800块钱了
问题的根源在于,2个线程会同时访问一个实例的某个成员变量,2条线程判断条件时成员变量的值均可能是还没取钱时候的值
要解决这个问题,我们可以这么想,取钱的时候(即调getMoney方法的时候),只允许1条线程访问,就解决了
代码如下:
package test;
public class FetchMoney {
public static void main(String[] args) {
Bank bank = new Bank();
MoneyThread thread1 = new MoneyThread(bank); // 柜台手续线程
MoneyThread thread2 = new MoneyThread(bank); // 自助机手续线程
thread1.start();
thread2.start();
}
}
class Bank {
private int money = 1000;
public synchronized int getMoney(int money) {
if(money < 0) {
return -1;
}
if(money > this.money) {
return -2;
}
try {
Thread.sleep(1000); // 取钱前的一些准备工作
} catch (Exception e) {
e.printStackTrace();
}
this.money -= money;
return money;
}
public int getMoney2(int money) {
synchronized(this) {
if (money < 0) {
return -1;
}
if (money > this.money) {
return -2;
}
try {
Thread.sleep(1000); // 取钱前的一些准备工作
} catch (Exception e) {
e.printStackTrace();
}
this.money -= money;
}
return money;
}
}
class MoneyThread extends Thread {
private Bank bank;
public MoneyThread(Bank bank) {
this.bank = bank;
}
@Override
public void run() {
System.out.println(bank.getMoney(800));
}
}
调用getMoney或者getMoney2都可以
结果为:
800
-2
Process finished with exit code 0
推荐阅读
-
JavaScript call apply使用 JavaScript对象的方法绑定到DOM事件后this指向问题_javascript技巧
-
WordPress迁移时一些常见问题的解决方法整理_PHP
-
同时访问两个php页面遇到的问题
-
老生常谈的问题,大三程序猿实习是去大公司呢,还是创业公司?
-
关于在linux中定时执行php文件的有关问题
-
求助,关于
- 宽度控制的问题_html/css_WEB-ITnose
-
apache2.4.6的httpd.conf设置问题
-
本人已接近奔溃,求各位解答下mamp环境下连接数据库和系统设置的几个小问题,不甚感激
-
PHP通过get获取传递url的值有关问题
-
如何写脚本像R大一样自动关注喜欢的问题?