在尝试运行彼此基于的2个线程时,我似乎遇到了有关死锁的问题。
代码是这样的:
Box.Java(Main)
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();
}
}
}
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。第二个线程似乎根本没有运行。它不会检索包装或插入包装并且不会释放锁定。任何关于如何解决这个问题的帮助/建议都表示赞赏,如果有人有一个好的设计模式提示,我会更乐于学习。
顺便说一下,该程序基本上模拟了一个盒子,它可以同时包含1个包装,如果它已经满了,顾客拉包装,如果它是空的,商店将放入1个包装。 / p>
编辑:
它与建议重复的不同,因为在另一个问题中,主线程没有java代码,因此它不包括我自己的问题的答案。
答案 0 :(得分:2)
您在单个线程中调用Shop和Customer的run()方法而不创建线程。
将shop.run();
替换为new Thread(shop).start()
将customer.run();
替换为new Thread(customer).start()
为他们开始新的线程
或者你可以扩展Thread而不是实现Runnable(它实现了Runnable)并像你一样覆盖Run方法并直接调用它们的start()方法。