银行取钱操作

银行取钱操作

定义账户类—临界资源

定义取钱线程

public class 取钱线程 extends Thread {
	private 账户类 account;//取钱的账户
	private double amount;//取钱的金额
	public 取钱线程(账户类 account,double amount) {
		this.account=account;
		this.amount=amount;
	}
	@Override
	public void run() {
		//首先判断余额是否满足
		if(account.getBalance()>amount) {
			//阻塞200ms,模拟取钱过程
			try {
				Thread.sleep(200); //不会释放锁
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			//调用账户类的方法实现取钱处理
			account.setBalance(account.getBalance()-amount);
		}
	}
}

存钱线程,用于模拟银行发工资。上账时间1000ms

public class 存钱线程 implements Runnable {
	private 账户类 account;
	private double amount;
	public 存钱线程(账户类 account,double salary) {
		this.account=account;
		this.amount=salary;
	}
	@Override
	public void run() {
		double dd=account.getBalance();
        try {
			Thread.sleep(1000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
        dd+=amount;
        account.setBalance(dd);
	}

}

定义主方法,模拟出现了针对同一个账户同时取钱和发钱的过程

账户类 account=new 账户类(1L, 10000.);
取钱线程 t1=new 取钱线程(account, 9000);
存钱线程 t2=new 存钱线程(account,500.);
t1.start();  t2.start();
t1.join();  
t2.join();
System.out.println(account.getBalance());

显示结果为10500.0,执行结果错误?

  • 共享同一个账户
  • 执行修改操作,但是没有进行同步约束

如果解决出现的错误:使用同步处理—synchronized—加锁

最简单的方法:

使用方法2的同步代码块,在修改操作上添加对应的同步处理

	public void run() {
		synchronized (account) {  //同步上下文
			//首先判断余额是否满足
			if(account.getBalance()>amount) {
				//阻塞200ms,模拟取钱过程
				try {
					Thread.sleep(200); //不会释放锁
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				//调用账户类的方法实现取钱处理
				account.setBalance(account.getBalance()-amount);
			}
		}
	}

最常见的比较好想的方法:

使用方法1的同步方法

public class 账户类 {
	private Long id;
	private Double balance;
	public 账户类(long l, double d) {
		this.id = l;
		this.balance = d;
	}
	public synchronized void 存钱(double salary) {
		double dd = balance;
		try {
			Thread.sleep(1000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		dd += salary;
		this.balance = dd;
	}
	public synchronized void 取钱(double amount) {
		// 首先判断余额是否满足
		if (balance > amount) {
			// 阻塞200ms,模拟取钱过程
			try {
				Thread.sleep(200); // 不会释放锁
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			// 调用账户类的方法实现取钱处理
			this.balance = this.balance - amount;
		}
	}

	public Double getBalance() {
		return this.balance;
	}
}

猜你喜欢

转载自blog.csdn.net/qq_45874107/article/details/113876382