0

同期を適切に使用していませんか?

次のコードでは、2 つの問題 があり
ます 。メソッド内でロックを取得するため、呼び出しを待機することになっています。IllegalMonitorStateExceptionと その両方を取得しています。synchronizedwait()IllegalMonitorStateExceptiondesignBusinessDesigner Threadwaitwait()notify()


synchronized2.特にキーワードを削除してsynchronized(this)ブロックを使用wait()してnotify()も、DEADLOCKを取得しました! なぜ?

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

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

第三に、作成者スレッドで

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 に答える