【问题标题】:meet IllegalMonitorStateException when doing multi-thread programming in Java在Java中做多线程编程时遇到IllegalMonitorStateException
【发布时间】:2016-10-13 04:22:33
【问题描述】:

我写了一个简单的程序来学习同步块。程序如下:

public class SychronizedBlock {

    static int balance = 0;
    static Integer lock = 0;


    public static void deposit(int amt) {
        Thread t1 = new Thread(new Runnable() {
            public void run() {
                acquire_lock();
                int holdings = balance;
                balance = holdings + amt;
                System.out.println("deposit " + amt + ", balance: " + balance);
                release_lock();
            }
        });
        t1.start();

    }

    public static void acquire_lock() {
        synchronized(lock) {
            while (lock == 1) {
                try {
                    lock.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            lock = 1;
        }
    }

    public static void release_lock() {
        synchronized(lock) {
            lock = 0;
            lock.notifyAll();
        }
    }

    public static void test1() {
        balance = 0;
        deposit(500);
        deposit(500);
    }

    public static void main(String[] args) {
        test1();
    }
}

但是,在运行程序时,我遇到了 IllegalMonitorStateException。我想我已经将 wait() 和 notifyAll() 函数放在了同步块中,并且我已经将锁设置为同步的参数。为什么我仍然有异常?

【问题讨论】:

    标签: java multithreading wait synchronized notify


    【解决方案1】:

    问题在于您的 release_lock 方法。您在调用lock.notifyAll(). 之前将lock 重新分配给0,这意味着将在未锁定的新整数对象上调用notifyAll。将代码更改为以下以解决问题。

    public static void release_lock() {
        synchronized(lock) {            
            lock.notifyAll();
            lock = 0;
        }
    }
    

    【讨论】:

    • 或者更好,只是避免更改lock 变量。很少 - 如果有的话 - 同步一个可以改变的变量是一个好主意。 (由于缓存效应,我也避免使用Integer 进行锁定。我通常更喜欢锁定一个普通的Object,它只是用于此目的。)
    • 得到它!非常感谢您的清晰解释!我没有意识到“lock = 0”语句之前会分配一个新对象来锁定。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-13
    • 1970-01-01
    • 1970-01-01
    • 2023-03-05
    • 1970-01-01
    相关资源
    最近更新 更多