Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/55.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java死锁,2个线程似乎相互阻塞_Java_Multithreading_Deadlock - Fatal编程技术网

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

Java死锁,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

我似乎遇到了一个关于死锁的问题,当我试图运行两个基于彼此的线程时

代码如下所示:

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 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();
        }

    }
}