Java死锁,2个线程似乎相互阻塞
我似乎遇到了一个关于死锁的问题,当我试图运行两个基于彼此的线程时 代码如下所示: Java(Main) Shop.javaJava死锁,2个线程似乎相互阻塞,java,multithreading,deadlock,Java,Multithreading,Deadlock,我似乎遇到了一个关于死锁的问题,当我试图运行两个基于彼此的线程时 代码如下所示: Java(Main) 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 b
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();
}
}
}
Customer.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。第二个线程似乎根本没有运行。它不会检索或插入包,也不会释放锁。任何关于如何克服这一问题的帮助/建议都将不胜感激,如果有人有好的设计模式技巧,我将非常乐意学习
顺便说一句,这个程序基本上模拟了一个盒子,里面可以一次装一个包裹,如果满了,顾客会拉包裹,如果是空的,商店会放一个包裹
编辑:
它与建议的复制不同,因为在另一个问题中,主线程没有java代码,因此它不包括我自己问题的答案。您在单个线程中调用Shop和Customer的run()方法,而不创建线程
替换shop.run()代码>使用新线程(shop).start()
替换customer.run()代码>使用新线程(客户)。开始()
为他们开始新的线程
或者,您可以扩展线程而不是实现Runnable(它仍然实现Runnable),并像您一样重写Run方法,直接调用它们的start()方法。您在单个线程中调用了商店和客户的Run()
方法,而无需创建线程。也许这就是问题所在?他们都在实施Runnable@DanielNetzer它们只是可运行的类。如果直接调用.run(),则在调用它们的线程上运行它们。看到我的答案了。很好,我已经玩了3个多小时了。等待和。通知。非常感谢你,伯克。
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();
}
}
}