简体   繁体   English

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

[英]Java deadlock, 2 threads seems to be blocking each other

I seem to have encountered a problem concerning a deadlock when trying to run 2 threads which are based on each other. 尝试运行基于彼此的2个线程时,我似乎遇到了有关死锁的问题。

The code is like this: 代码是这样的:

Box.Java (Main) 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 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 客户.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();
        }

    }
}

I do not get any error from the Console, but it only prints the first syso on the the thread I run first. 我没有从控制台得到任何错误,但是它只在我首先运行的线程上输出第一个syso。 The 2nd thread doesn't seem to run at all. 第二个线程似乎根本没有运行。 It doesn't retrieve the package or insert it and doesn't release the lock. 它不会检索或插入包,也不会释放锁。 Any help/advice on how to get past this issue is appreciated and if anyone has a good design pattern tips I'll be more then happy to learn. 感谢您提供有关如何解决此问题的帮助/建议,如果有人有好的设计模式提示,我将非常乐于学习。

By the way, the program basically simulates a box which can contain 1 package at once, if it's full the customer pulls the package, if it's empty the shop will put in 1 package. 顺便说一句,该程序基本上模拟了一个盒子,该盒子可以一次容纳1个包装,如果装满了,则客户将其拉出,如果是空的,商店将放入1个包装。

EDIT: 编辑:

its diffrent from what suggested as duplicate since in the the other question there is no java code for the main thread so it doesnt include the answer to my own question. 它与建议重复的内容有所不同,因为在另一个问题中主线程没有Java代码,因此它不包含我自己问题的答案。

You're calling run() method of Shop and Customer in a single thread without creating thread. 您在一个线程中调用Shop和Customer的run()方法,而不创建线程。

Replace shop.run(); 替换shop.run(); with new Thread(shop).start() new Thread(shop).start()

Replace customer.run(); 替换customer.run(); with new Thread(customer).start() new Thread(customer).start()

to start new Thread for them 为他们启动新线程

or you can extend Thread instead of implementing Runnable (it implements Runnable anyway) and override the Run method just like you and invoke start() method of them directly. 或者,您可以扩展Thread而不是实现Runnable(无论如何都实现Runnable),并像您一样重写Run方法并直接调用它们的start()方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM