使用JAVA语言设计一个程序,使用两个线程模拟在两个地点同时从一个账号中取钱,假如卡中一共有1000元,每个线程取800元,要求演示结果一个线程取款成功,剩余200元,另一个线程取款失败,余额不足; 要求: 1:使用线程池创建线程 2:解决线程安全问题
时间: 2024-10-14 22:12:00 浏览: 21
在Java中,我们可以使用`synchronized`关键字和`ReentrantLock`等同步机制来解决这个线程安全问题,确保在取款过程中不会发生数据竞争。下面是一个简单的示例,我们将使用`ExecutorService`创建线程池,并创建两个`DepositAndWithdrawThread`类,这两个线程会尝试从共享的`Account`对象中各自取出800元:
```java
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
class Account {
private int balance = 1000; // 卡中总金额
public synchronized void withdraw(int amount) throws InterruptedException {
if (amount <= balance) {
System.out.println(Thread.currentThread().getName() + "尝试取款:" + amount);
balance -= amount;
System.out.println(Thread.currentThread().getName() + "取款完成,余额:" + balance);
} else {
throw new InsufficientBalanceException("余额不足");
}
notifyAll(); // 通知其他等待的线程
}
public synchronized void deposit(int amount) {
balance += amount;
System.out.println(Thread.currentThread().getName() + "存款:" + amount);
}
}
class DepositAndWithdrawThread extends Thread {
private final Account account;
public DepositAndWithdrawThread(Account account, String name) {
this.account = account;
setName(name);
}
@Override
public void run() {
try {
account.deposit(800); // 先存款确保有足够金额
account.withdraw(800); // 再尝试取款
} catch (InsufficientBalanceException e) {
System.out.println(getName() + "取款失败:" + e.getMessage());
}
}
}
public class Main {
public static void main(String[] args) {
ExecutorService executor = Executors.newFixedThreadPool(2); // 创建线程池
Account sharedAccount = new Account();
// 启动取款和存款任务
executor.execute(new DepositAndWithdrawThread(sharedAccount, "Thread-1"));
executor.execute(new DepositAndWithdrawThread(sharedAccount, "Thread-2"));
// 关闭线程池
executor.shutdown();
}
}
```
在这个例子中,我们通过`synchronized`保证了对`withdraw`和`deposit`方法的互斥访问,避免了并发取款导致的异常情况。
阅读全文