0

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

在以下代码中,我遇到了 2 个问题:
1. 在这种情况下制作方法(designBusiness、createBusiness、sellBusiness)synchronized时,打电话wait()IllegalMonitorStateException 但我不明白为什么?因为在designBusiness方法中Designer Thread确实获得了锁,所以它应该等待wait调用。我得到了 IllegalMonitorStateExceptionwait()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

4 回答 4

2

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

您正在调用的 wait() 方法在您正在创建的匿名内部类的实例上执行。您从中创建它的同步方法在不同的对象上同步,并且它可能在内部对象到达 wait() 调用时也已经执行。

您需要在此处整理出哪个对象是哪个。可能您需要调用 Main.this.wait(),但这取决于您认为您正在尝试做什么,这从您的问题中不清楚。

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

于 2013-07-08T11:59:49.687 回答
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();

二、在设计师线程中

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

三、在creator线程中

synchronized (lock) {
    lock.notifyAll();
}
于 2013-07-08T11:58:17.350 回答
0

wait()必须从synchronized同一监视器上的块执行。由于wait()this.wait()您必须用以下方式包装它相同synchronized(this)

synchronized(this) {
    wait();
}
于 2013-07-08T11:17:11.337 回答
0

如果您尝试通过未由该线程锁定的线程来解锁 onject,那么您最终可能会遇到相同的错误。

于 2013-08-01T10:50:07.810 回答