【发布时间】:2021-01-18 23:35:31
【问题描述】:
我目前正在使用 java 中的锁和同步方法。我有一个包含三个类的示例程序:一个帐户,具有两种取款和存款方法以及一个共享的可变余额;以及 Spender 和 Saver 类。
class Account{
private float balance = 0;
public void depositMoney(float amount){
float tmp;
synchronized(this){
tmp = balance;
System.out.println("(Adding money): the initial balance is: "
+ tmp);
tmp +=amount;
balance = tmp;
System.out.println("(Adding money): the final balance is: "
+ balance);
this.notify();
}
}
public void withdrawMoney(float amount){
float tmp;
synchronized(this){
while (balance <= 0){
try {
this.wait();
} catch (Exception e) {}
}
tmp = balance;
System.out.println("(Withdrawing money): the initial balance is: "
+ tmp);
tmp -=amount;
balance = tmp;
System.out.println("(Withdrawing money): the final balance is: "
+ balance);
}
}
}
class Saver extends Thread{
private Account account;
Scrooge(Account account){
this.account = account;
}
public void run(){
for (int i=0; i < 2; i++){
account.depositMoney(1200);
}
}
}
class Spender extends Thread{
private Account account;
Donald(Account account){
this.account = account;
}
public void run(){
for (int i=0; i< 2; i++){
account.withdrawMoney(400);
}
}
}
public class Bankv4{
public static void main(String[] args){
Account account = new Account();
Spender s1 = new Spender(account);
Spender s2 = new Spender(account);
Spender s3 = new Spender(account);
Saver saver = new Saver(account);
s1.start();
s2.start();
s3.start();
saver.start();
}
}
问题是这段代码并不总是有效。它适用于 Saver 类运行 depositMoney 方法 30 次,数量为 100,Spender 类运行提款 10 次,数量为 100 的情况(因为有 3 个 Spender 线程 10 * 3 * 100 = 3000, Saver 类存入账户的金额)。
在上面的代码中,问题是虽然 Saver 类存入的数量与 Spender 提取的数量相同,但它的迭代次数较少,这会导致死锁,因为 Spender 线程运行 wait() 但 Saver 类由于其线程已结束,not run notify() 不运行,导致程序无法完成。
谁能解决这个问题?提前致谢
【问题讨论】:
-
小问题:实现 Runnable 比扩展 Thread 更好。最好还是使用更新的 Java 更高级别的并发对象
-
另一个明显的狡辩是,这不是现实的代码,没有人会真正以这种方式编写线程。尝试实现一些线程原语可能更有用,例如信号量或线程安全队列。 (但我意识到这可能只是一个例子。)
标签: java multithreading