简介:
本文主要通过模拟取钱的流程来记录对多线程下共用变量的值的处理;假设张三和李四两兄弟取银行取统一账户下的钱,一个人拿着银行卡在自动取款机取钱,一个拿着存折在柜台取钱,账户上有10000元,假设两人都想取6000元。
由于我们没有使用同步关键字加锁,所以会出现两个人同时能取2000的情况,这种情况显然是不允许的。
解决方法就是通过加synchronized关键字锁住对象类就可以了;接下来我们就通过代码来模拟:
假设业务场景如下:
张三和李四两兄弟取银行取统一账户下的钱,一个人拿着银行卡在自动取款机取钱,一个拿着存折在柜台取钱,账户上有10000元,假设两人都想取6000元。
代码实现:
新建一个账户类Account.java
package com.democxy.thread; import java.util.Date; /** * 定义账户 * @author democxy * */ public class Account { //定义账户余额 public static double money = 10000; /** * 取钱方法 * @param outMoney 要取的钱 * synchronized 关键字,锁住Account对象,直到当前执行withOutMoney方法的线程执行完毕后才释放对象,其他线程才可用 */ public synchronized void withOutMoney(double outMoney) { //获取线程名字 String name = Thread.currentThread().getName(); System.out.println(new Date().toLocaleString()+name+"本次取钱:"+outMoney+"元"); if (outMoney<money) { money = money-outMoney; System.out.println(new Date().toLocaleString()+name+"取钱结束...........账户还剩"+money+"元"); }else { System.out.println(new Date().toLocaleString()+name+"取钱失败,原因:余额不足,当前只有"+money+"元"); System.out.println("--------------------------"); System.out.println("--------------------------"); System.out.println("--------------------------"); } } }
新建一个线程类User .java
package com.democxy.thread; import java.util.Date; public class User implements Runnable { //定义账户 Account account; //定义取钱金额 double outMoney; public User(Account account, double outMoney) { this.account = account; this.outMoney = outMoney; } @Override public void run() { try { //让线程休息1秒,模拟输入密码的过程 Thread.sleep(1000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } //获取线程名字 String name = Thread.currentThread().getName(); System.out.println(new Date().toLocaleString()+name+"输完密码,账户当前余额:"+account.money+"元,开始取钱............"); //执行取钱的方法 account.withOutMoney(outMoney); } }
新建一个执行类
package com.democxy.thread; /** * 多线程demo * @author democxy * */ public class ThreadDemo { public static void main(String[] args) { Account account = new Account(); double outMoney = 6000; User user = new User(account, outMoney); Thread thread1 = new Thread(user,"张三"); Thread thread2 = new Thread(user,"李四"); thread1.start(); thread2.start(); } }
执行结果1:
执行结果2: