[英]Deadlock situation using threads in java?
我创建了 3 个类,
Client
线程应wait()
,直到InCharge
线程完成测试(15 秒)InCharge
线程运行时Client
线程应该等到InCharge
线程说Notify()
Synchronized
块的锁定。 根据我的调试,似乎是InCharge
发送了Notify()
但由于某种原因客户端没有收到通知,我猜问题是因为while(true)
,但我想不出解决方法.
你能帮忙找出问题吗?
主要的:
public class Main {
public static void main(String[] args) {
Object obj = new Object();
Bank bank = new Bank(100000);
Client client1 = new Client(obj, bank);
InCharge inCharge = new InCharge(obj, bank);
client1.setName("client1");
inCharge.setName("inCharge");
client1.start();
inCharge.start();
}
}
银行:
public class Bank {
private int balance;
private boolean bankIsClose = false;
public Bank(int balance) {
this.balance = balance;
}
public int getBalance() {
return balance;
}
public boolean isBankIsClose() {
return bankIsClose;
}
public void setBankIsClose(boolean bankIsClose) {
this.bankIsClose = bankIsClose;
}
public void setBalance(int balance) {
this.balance = balance;
}
public synchronized void withdraw(String name, int amount){
if (this.balance - amount >= 0) {
this.balance = this.balance - amount;
System.out.println(name+" "+this.balance + " withdrawed - " + amount);
}
}
}
客户:
public class Client extends Thread {
private Object obj;
private Bank bank;
Client(Object obj, Bank bank) {
this.obj = obj;
this.bank = bank;
}
@Override
public void run() {
int randomNumber;
while (bank.getBalance() > 0) {
synchronized (obj) {
randomNumber = ((int) (Math.random() * (5000 - 1000 + 1)) + 1000);
if (!bank.isBankIsClose()) {
try {
obj.wait();
bank.withdraw(currentThread().getName(), randomNumber);
} catch (Exception e) {}
}
}
}
}
}
负责:
public class InCharge extends Thread {
private Object obj;
private Bank bank;
InCharge(Object obj, Bank bank) {
this.obj = obj;
this.bank = bank;
}
@Override
public void run() {
while (true) {
synchronized (obj) {
bank.setBankIsClose(true);
try {
System.out.println("Charge is here!, current balance is: " + bank.getBalance());
Thread.sleep(5000);
} catch (InterruptedException e) {}
bank.setBankIsClose(false);
obj.notify();
}
}
}
}
您的应用程序确实为我运行而无需更改,但由于银行开/闭环的性质,银行不是很友好。
银行关闭 5 秒,然后打开,但会立即尝试再次进入同步块以关闭银行。 有时 InCharge/bank 线程会击败客户端线程以访问synchronized(obj)
。 这是正常的,也是意料之中的,但这意味着在许多周期中,银行会继续休眠(5000),而上一个周期显示的余额相同,并且在这之间没有客户提款代码运行。
为了模拟银行的正常工作时间,您可以在 InCharge 线程中同步后添加第二个小 sleep(),此期间将显示客户端更频繁地获取锁以进行提款。 将 InCharge.run() 更改为:
public void run() {
while (true) {
synchronized (obj) {
bank.setBankIsClose(true);
try {
System.out.println("Charge is here!, current balance is: " + bank.getBalance());
Thread.sleep(5000);
} catch (InterruptedException e) {}
bank.setBankIsClose(false);
System.out.println("Now the bank is open for business");
obj.notify();
}
// Simulate a period of bank being open:
try {
Thread.sleep(1000);
} catch (InterruptedException e) {}
}
}
如果您进一步开发应用程序,您应该尝试 2 个客户端线程,并且需要将notify()
更改为notifyAll()
以确保所有客户端都有机会使用银行。 还将您的代码更改为 Runnable 而不是扩展 Thread 将使代码更清晰。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.