有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

多线程Java同步IllegalMonitorStateException

我是否没有正确使用同步:

在下面的代码中,我遇到了两个问题:
1。在本例中,虽然将方法(designBusiness、createBusiness、sellBusiness)设置为synchronized类似,但对wait()的调用会显示IllegalMonitorStateException,但我不明白为什么?因为在designBusiness方法Designer Thread中确实获得了锁,所以它应该等待wait调用。我在wait()notify()这两个方面都得到了非法监视状态例外


2。即使当我删除synchronized关键字,并使用synchronized(this)块来处理wait()notify()时,我还是死锁了!为什么

public class Main {
  HashMap<String, Integer> map = new shop().orderBook();

  public static void main(String[] args) throws InterruptedException {

    Main main = new Main();

    main.sellBusiness();
    Thread.sleep(3000);
    main.designBusiness();
    Thread.sleep(3000);
    main.createBusiness();
  }

  private synchronized void designBusiness() throws InterruptedException {

    Thread designThread = new Thread(new Runnable() {
      public void run() {
        Set set = map.keySet();
        System.out.println("Tracking OrderList");
        System.out.println(set.size());
        try {

          System.out.println("waiting.........");
          wait();
          System.out.println("wait completed");

          System.out.println("after design process items in orderList are "
              + map.keySet().size());
        } catch (InterruptedException e) {
          e.printStackTrace();
        }
      }

    }, "Designer Thread");
    designThread.start();
    System.out
    .println("status of Designer Thread" + designThread.isAlive());
  }

  private synchronized void createBusiness() throws InterruptedException {
    Thread createThread = new Thread(new Runnable() {

      public void run() {
        System.out.println(Thread.currentThread().getName()
            + " started");
        Creator creator = new Creator();
        creator.create(map);
        notifyAll();
        System.out.println("notified");

      }
    }, "Creator Thread");
    createThread.start();
    createThread.join();
    System.out.println("status of Creator Thread" + createThread.isAlive());
  }

  private void sellBusiness() throws InterruptedException {
    Thread sellThread = new Thread(new Runnable() {
      public void run() {
        Seller seller = new Seller();
        seller.sellGold(45000, 15);
        seller.sellSilver(14000, 60);
        seller.noteOrder("Mrs Johnson", 15000, map);
        seller.noteOrder("Mr. Sharma", 10000, map);
        seller.sellGold(60000, 20);
        seller.noteOrder("Mr. Hooda", 17500, map);
        System.out.println(Thread.currentThread().getName()
            + " done selling");
      }
    }, "Seller Thread");
    sellThread.start();
    sellThread.join();
    System.out.println("status of seller Thread" + sellThread.isAlive());
  }
}

请帮助我,我找不到任何解决这个问题的方法,我从昨晚开始搜索


共 (4) 个答案

  1. # 1 楼答案

    wait()notify()notifyAll()必须与synchronized一起使用。我要做的是努力解决僵局


    为了说明为什么会出现死锁(无关代码被删除)(如果我猜对了)

    public class Main {
        public static void main(String[] args) throws InterruptedException {
            Main main = new Main();
            main.createBusiness();
        }
        private synchronized void createBusiness() throws InterruptedException {
    //          ^^^^^^^^^^^^ got lock
            Thread createThread = new Thread(new Runnable() {
                public void run() {
                    synchronized (Main.this) {
    //              ^^^^^^^^^^^^^^^^^^^^^^^^ try to get lock --> DEADLOCK
                        Main.this.notifyAll();
                    }
                }
            });
            createThread.start();
            createThread.join();
    //      ^^^^^^^^^^^^^^^^^^^ wait for createThread to die --> DEADLOCK
        }
    }
    
    1. 主线程得到了Main.this的锁
    2. createThread试图获得Main.this的锁,但它被Main.this锁定,因此等待
    3. 主线程等待createThread死亡,因此等待(2和3可以互换)

    由于我不确定您试图实现的目标,我不确定以下解决方案是否正确,但您可以尝试(即使上述猜测是错误的):

    首先,创建一个lock对象

    public class Test {
        private Object lock = new Object();
    

    第二,在designer线程中

    synchronized (lock) {
        lock.wait();
    }
    

    第三,在creator线程中

    synchronized (lock) {
        lock.notifyAll();
    }
    
  2. # 2 楼答案

    如果您试图通过threas解锁一个未被该线程锁定的onject,则可能会出现相同的错误

  3. # 3 楼答案

    如果出现此异常,则您不在等待的对象上同步的块或方法中。这就是例外的含义。唯一的意义

    您正在调用的wait()方法将在您正在创建的匿名内部类的实例上执行。创建它的同步方法是在另一个对象上同步的,而且在内部对象到达wait()调用时,它可能已经执行了

    你需要弄清楚这里哪个物体是哪个。也许你需要打电话给梅因。这等等(),但这取决于你想做什么,这在你的问题中并不清楚

    注意,你没有遇到死锁,你得到的是一个无限块。这不是一回事

  4. # 4 楼答案

    wait()必须从同一监视器上的synchronized块执行。因为wait()this.wait()相同,所以必须用synchronized(this)来包装它:

    synchronized(this) {
        wait();
    }