|
@@ -0,0 +1,114 @@
|
|
|
+package com.sf.thread_new.bank;
|
|
|
+
|
|
|
+// 银行取钱窗口
|
|
|
+// 模拟多人在不同窗口取钱的场景
|
|
|
+public class DrawThread extends Thread {
|
|
|
+
|
|
|
+ // 操作的账户
|
|
|
+ private Account account;
|
|
|
+ // 取款金额
|
|
|
+ private double drawAmount;
|
|
|
+
|
|
|
+ // 创建构造器 同时调用父类的构造器
|
|
|
+ public DrawThread(String name, Account account, double drawAmount) {
|
|
|
+ super(name);
|
|
|
+ this.account = account;
|
|
|
+ this.drawAmount = drawAmount;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void run() {
|
|
|
+ // 取钱操作
|
|
|
+ account.handle(drawAmount);
|
|
|
+// handle2(account,drawAmount);
|
|
|
+ }
|
|
|
+
|
|
|
+ public synchronized void handle(){}
|
|
|
+ public void handle1(){
|
|
|
+ // 如果synchronized 修饰的是非静态方法 锁住的是当前对象 this = new DrawThread()
|
|
|
+ synchronized (this){}
|
|
|
+ }
|
|
|
+ public synchronized static void handle2(Account account, double drawAmount){
|
|
|
+// if (account.getBalance() >= drawAmount) {
|
|
|
+// try {
|
|
|
+// Thread.sleep(200);
|
|
|
+// } catch (InterruptedException e) {
|
|
|
+// throw new RuntimeException(e);
|
|
|
+// }
|
|
|
+//
|
|
|
+// account.setBalance(account.getBalance() - drawAmount);
|
|
|
+// System.out.println(Thread.currentThread().getName() + "取钱成功,余额为:" + account.getBalance());
|
|
|
+// } else {
|
|
|
+// System.out.println(Thread.currentThread().getName() + "余额不足");
|
|
|
+// }
|
|
|
+ }
|
|
|
+ public void handle3(){
|
|
|
+ // 如果synchronized 修饰的是静态方法 锁住的是类对象
|
|
|
+ synchronized (DrawThread.class){}
|
|
|
+ }
|
|
|
+
|
|
|
+ public static void main(String[] args) {
|
|
|
+ Account account = new Account("001", 1000);
|
|
|
+// new DrawThread("zhangsan", account, 600).start();
|
|
|
+
|
|
|
+ // 构造多人 触发余额为负数的情况
|
|
|
+ // 出现原因是:多个线程都对账户的余额进行扣减
|
|
|
+ for (int i = 0; i < 10; i++) {
|
|
|
+ new DrawThread(i + "", account, 600).start();
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+class Account {
|
|
|
+ private String accountNo;
|
|
|
+ private double balance;
|
|
|
+
|
|
|
+ public Account() {
|
|
|
+ }
|
|
|
+
|
|
|
+ public Account(String accountNo, double balance) {
|
|
|
+ this.accountNo = accountNo;
|
|
|
+ this.balance = balance;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 使用synchronized来修饰方法 代表方法被加了锁
|
|
|
+ // 只有一个线程能获取锁 然后执行方法 其他线程此时要等待
|
|
|
+ // 当此线程执行完 释放锁 其他等待的线程再争抢锁
|
|
|
+ // 如果在方法上加锁 代表是 以当前对象作为锁 来被争抢
|
|
|
+
|
|
|
+ // 把取钱逻辑从窗口 挪到账户中
|
|
|
+ // 此时先判断 账户是否被其他线程获取 如果是 等待 如果不是 那么获取账户锁
|
|
|
+ public synchronized void handle(double drawAmount){
|
|
|
+ if (this.balance >= drawAmount) {
|
|
|
+ try {
|
|
|
+ Thread.sleep(200);
|
|
|
+ } catch (InterruptedException e) {
|
|
|
+ throw new RuntimeException(e);
|
|
|
+ }
|
|
|
+
|
|
|
+ this.balance = balance - drawAmount;
|
|
|
+ System.out.println(Thread.currentThread().getName() + "取钱成功,余额为:" + balance);
|
|
|
+ } else {
|
|
|
+ System.out.println(Thread.currentThread().getName() + "余额不足");
|
|
|
+ }
|
|
|
+
|
|
|
+// synchronized (this) {}
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ public String getAccountNo() {
|
|
|
+ return accountNo;
|
|
|
+ }
|
|
|
+
|
|
|
+ public void setAccountNo(String accountNo) {
|
|
|
+ this.accountNo = accountNo;
|
|
|
+ }
|
|
|
+
|
|
|
+ public double getBalance() {
|
|
|
+ return balance;
|
|
|
+ }
|
|
|
+
|
|
|
+ public void setBalance(double balance) {
|
|
|
+ this.balance = balance;
|
|
|
+ }
|
|
|
+}
|