Java同步-IllegalMonitorStateException

Java同步-IllegalMonitorStateException,java,multithreading,synchronization,locking,Java,Multithreading,Synchronization,Locking,我是否未正确使用同步: 在以下代码中,我有两个问题: 一,。当将方法(designBusiness、createBusiness、sellBusiness)设置为与本例类似的synchronized时,调用wait()会显示IllegalMonitorStateException,但我不明白为什么?因为在designBusiness方法Designer线程中确实获得了锁,所以它应该等待wait调用。我在wait()和notify()上都收到非法的MonitorStateException 2.即

我是否未正确使用同步:

在以下代码中,我有两个问题:
一,。当将方法(designBusiness、createBusiness、sellBusiness)设置为与本例类似的
synchronized
时,调用
wait()
会显示
IllegalMonitorStateException
,但我不明白为什么?因为在
designBusiness
方法
Designer线程
中确实获得了锁,所以它应该等待
wait
调用。我在
wait()
notify()
上都收到非法的MonitorStateException


2.即使当我删除
synchronized
关键字并使用
synchronized(此)
块,特别是
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());
  }
}
公共类主{
HashMap map=new shop().orderBook();
公共静态void main(字符串[]args)引发InterruptedException{
Main Main=新Main();
main.sellBusiness();
睡眠(3000);
main.designBusiness();
睡眠(3000);
main.createBusiness();
}
private synchronized void designBusiness()引发InterruptedException{
线程设计线程=新线程(新可运行(){
公开募捐{
Set=map.keySet();
System.out.println(“跟踪订单列表”);
System.out.println(set.size());
试一试{
System.out.println(“等待…”);
等待();
System.out.println(“等待完成”);
System.out.println(“订单列表中的设计后流程项为”
+map.keySet().size());
}捕捉(中断异常e){
e、 printStackTrace();
}
}
}“设计师线程”);
designThread.start();
系统输出
.println(“设计器线程的状态”+designThread.isAlive());
}
private synchronized void createBusiness()引发InterruptedException{
线程createThread=新线程(new Runnable(){
公开募捐{
System.out.println(Thread.currentThread().getName())
+“启动”);
创建者=新的创建者();
creator.create(地图);
notifyAll();
系统输出打印项次(“已通知”);
}
}“创作者线程”);
createThread.start();
createThread.join();
System.out.println(“创建者线程状态”+createThread.isAlive());
}
私有void sellBusiness()引发InterruptedException{
Thread sellThread=新线程(new Runnable(){
公开募捐{
卖方=新卖方();
卖方:sellGold(45000,15);
卖方:白银(14000,60);
卖方票据订单(“约翰逊夫人”,15000,地图);
卖方票据订单(“Sharma先生”,10000,地图);
卖方:sellGold(60000,20);
卖方票据订单(“Hooda先生”,17500,地图);
System.out.println(Thread.currentThread().getName())
+“完成销售”);
}
}“卖方线程”);
sellThread.start();
sellThread.join();
System.out.println(“卖方线程状态”+sellThread.isAlive());
}
}
请帮助我无法找到此问题的任何解决方案,我正在从昨晚开始搜索。

wait()
必须从同一监视器上的
synchronized
块执行。由于
wait()
this.wait()
相同,因此必须用
synchronized(this)
将其包装起来:

wait()
必须从同一监视器上的
synchronized
块执行。由于
wait()
this.wait()
相同,因此必须用
synchronized(this)
将其包装起来:

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


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

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
    }
}
  • 主线程获得了
    Main的锁。此
  • createThread
    试图获得
    Main的锁。此
    ,但被
    Main锁定。此
    ,因此等待
  • 主线程等待
    createThread
    死亡,因此等待。(2和3可以互换)

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

    首先,创建一个
    lock
    对象

    public class Test {
        private Object lock = new Object();
    
    第二,在设计器线程中

    synchronized (lock) {
        lock.wait();
    }
    
    第三,在创建线程中

    synchronized (lock) {
        lock.notifyAll();
    }
    
    wait()
    notify()
    notifyAll()
    必须与
    同步的
    一起使用。我要做的是努力解决僵局


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

    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
        }
    }
    
  • 主线程获得了
    Main的锁。此
  • createThread
    试图获得
    Main的锁。此
    ,但被
    Main锁定。此
    ,因此等待
  • 主线程等待
    createThread
    死亡,因此等待。(2和3可以互换)

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

    首先,创建一个
    lock
    对象

    public class Test {
        private Object lock = new Object();
    
    第二,在设计器线程中

    synchronized (lock) {
        lock.wait();
    }
    
    第三,在创建线程中

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

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

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

    你需要弄清楚这里哪个物体是哪个。可能您需要调用Main.this.wait(),但这取决于您使用的是什么