gpt4 book ai didi

Java死锁,2个线程似乎互相阻塞

转载 作者:行者123 更新时间:2023-12-02 04:04:41 24 4
gpt4 key购买 nike

在尝试运行两个相互依赖的线程时,我似乎遇到了有关死锁的问题。

代码是这样的:

Box.Java(主要)

package exe4;

public class Box {

private static boolean boxStatus;
static Thread boxThread = Thread.currentThread();

public Box(){
Box.boxStatus = true;
}

public static void main(String[] args) throws InterruptedException{
Box box = new Box();
Shop shop = new Shop(box, "Post Office");
Customer customer = new Customer(box, "Daniel Netzer");

shop.run();
customer.run();

Thread.sleep(60000);
}

public boolean isBoxStatus() {
return boxStatus;
}

public void setBoxStatus(boolean boxStatus) {
Box.boxStatus = boxStatus;
}

}

Shop.java

package exe4;

public class Shop implements Runnable{

private static Box box;
private static String name;
private static Object shopLock = new Object();

public Shop(Box box, String name){
Shop.box = box;
Shop.name = name;
}

public static Object getShopLockMonitor(){
return Shop.shopLock;
}

public String getName() {
return name;
}

public synchronized void setName(String name) {
Shop.name = name;
}

public static Box getBox() {
return box;
}

public synchronized void setBox(Box box) {
Shop.box = box;
}

public synchronized void depositBox(){
Shop.box.setBoxStatus(true);
synchronized(Customer.getCustomerLockMonitor()){
Customer.getCustomerLockMonitor().notifyAll();}
}

public synchronized void printDeposit(){
System.out.println("New package have been deposited into your box.");
}

@Override
public void run() {
while(Box.boxThread.isAlive()){
while(box.isBoxStatus()){
synchronized(Shop.getShopLockMonitor()){
try {
System.out.println("Box is full, waiting for customer withdrawal.");
Shop.getShopLockMonitor().wait();
} catch (InterruptedException e) {}
}
}
depositBox();
printDeposit();
}
}
}

客户.java

package exe4;

public class Customer implements Runnable{

private static Box box;
private static String name;
private static Object customerLock = new Object();

public Customer(Box box, String name){
Customer.box = box;
Customer.name = name;
}

public static Object getCustomerLockMonitor(){
return Customer.customerLock;
}

public String getName() {
return name;
}

public synchronized void setName(String name) {
Customer.name = name;
}

public static Box getBox() {
return box;
}

public synchronized void setBox(Box box) {
Customer.box = box;
}

public synchronized void withdrawBox(){
Customer.box.setBoxStatus(false);
synchronized(Shop.getShopLockMonitor()){
Shop.getShopLockMonitor().notifyAll();}
}

public synchronized void printWithdraw(){
System.out.println("Package have been withdrawed from box.");
}

@Override
public void run() {
while(Box.boxThread.isAlive()){
while(!box.isBoxStatus()){
synchronized(Customer.getCustomerLockMonitor()){
try {
System.out.println("Box is empty, waiting for a new package to arrive.");
Customer.getCustomerLockMonitor().wait();
} catch (InterruptedException e) {}
}
}
withdrawBox();
printWithdraw();
}

}
}

我没有从控制台收到任何错误,但它只打印我首先运行的线程上的第一个 syso。第二个线程似乎根本没有运行。它不会检索包裹或插入包裹,也不会释放锁。任何有关如何解决此问题的帮助/建议都将受到赞赏,如果有人有好的设计模式技巧,我将非常乐意学习。

顺便说一句,该程序基本上模拟了一个盒子,它可以一次容纳 1 个包裹,如果满了,顾客就会拉出包裹,如果空了,商店就会放入 1 个包裹。

编辑:

它与建议的重复内容不同,因为在另一个问题中没有主线程的 java 代码,因此它不包含我自己问题的答案。

最佳答案

您在单个线程中调用 Shop 和 Customer 的 run() 方法,而不创建线程。

shop.run(); 替换为 new Thread(shop).start()

customer.run(); 替换为 new Thread(customer).start()

为他们启动新线程

或者你可以扩展Thread而不是实现Runnable(它无论如何都实现Runnable)并像你​​一样重写Run方法并直接调用它们的start()方法。

关于Java死锁,2个线程似乎互相阻塞,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34475530/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com