Java同步-IllegalMonitorStateException

时间:2013-07-08 11:15:00

标签: java multithreading synchronization locking

我没有正确使用同步:

在下面的代码中我有两个问题:
1。虽然像synchronized那样将方法(designBusiness,createBusiness,sellBusiness)设为wait(),但是对IllegalMonitorStateException的调用说designBusiness,但我不明白为什么?因为在Designer Thread方法wait中确实会获得锁定,因此它应该等待wait()调用。我在notify()synchronized上都收到了IllegalMonitorStateException。


2.即使我删除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()); } } 仍然有DEADLOCK!为什么?

{{1}}

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

4 个答案:

答案 0 :(得分:2)

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

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

你需要在这里找出哪个对象。可能你需要调用Main.this.wait(),但这取决于你认为你想要做什么,这在你的问题中并不清楚。

注意,你没有陷入僵局,你正在获得一个无限的障碍。这不是一回事。

答案 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可以交换)

  4. 由于我不确定你想要达到的目标,我不确定以下是否是正确的解决方案,但你可以尝试(即使上面猜错了):

    首先,创建一个lock对象。

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

    其次,在设计师线程中

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

    第三,在创作者线程中

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

答案 2 :(得分:0)

必须在同一监视器上的wait()块执行

synchronized。由于wait()this.wait()相同,因此您必须使用synchronized(this)包裹它:

synchronized(this) {
    wait();
}

答案 3 :(得分:0)

如果您尝试通过未被该线程锁定的线程解锁对象,则可能会出现相同的错误。