首页 > 解决方案 > 为什么我会使用此代码获得 IllegalMonitorStateException?

问题描述

我有 2 个线程,一个调用 get() 方法,另一个调用 put() 方法。我需要同步这些方法,以便在 put 之后才能看到 get 的结果。我确实知道如何以其他方式执行此操作,但我想了解为什么我会使用此代码获得 .IllegalMonitorStateException。

public class TransferObject {

    private int value;
    protected volatile boolean isValuePresent = false; //use this variable

    public synchronized int get() {
        synchronized (TransferObject.class) {

            System.out.println("Got: " + value);
            notify();
        }
        return value;
    }


    public void put(int value) {

        synchronized (TransferObject.class) {
            this.value = value;
            System.out.println("Put: " + value);
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

    }
}

这是2个线程的示例。

public class ConsumerTask implements Runnable {
    private TransferObject transferObject;
    protected volatile boolean stopped;

    public ConsumerTask(TransferObject transferObject) {
        this.transferObject = transferObject;
        new Thread(this, "ConsumerTask").start();
    }

    public void run() {
        while (!stopped) {
            transferObject.get();
        }
    }

    public void stop() {
        stopped = true;
    }
}


public class ProducerTask implements Runnable {

    private TransferObject transferObject;
    protected volatile boolean stopped;
    static volatile AtomicInteger i = new AtomicInteger(0);

    public ProducerTask(TransferObject transferObject) {
        this.transferObject = transferObject;
        new Thread(this, "ProducerTask").start();
    }

    public void run() {
        while (!stopped) {
            transferObject.put(i.incrementAndGet());
        }
    }

    public void stop() {
        stopped = true;
    }
}

标签: java

解决方案


您有两个线程和一个用于锁定的对象TransferObject.class。当您的线程 ConsumerTask 获得锁时,对象TransferObject.class没有睡眠线程,并且当您为此监视器调用 notify() 时,您会得到IllegalMonitorStateException

从方法通知的描述中:

Wakes up a single thread that is waiting on this object's monitor.

你没有等待监视器的踏板TransferObject.class


推荐阅读