IllegalMonitorStateException

来源:互联网 发布:php中级面试题 编辑:程序博客网 时间:2024/06/07 17:29

使用notify时必须持有对象的监视器,否则会报该异常。基本数据类型对应的类是final类时,此处有坑(在给这些final类的对象赋值时其实是产生了新对象,所以即使加锁,也是对新对象的加锁,不是同一对象的锁,也会产生该异常)。以下代码为证。

import java.util.ArrayList;

class Flag {
int value = 0;
public void change() {
value = 1;
notify();
}

public int get() {
while (value == 0)
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

return value;
}
}


public class Main {

static Flag flag = new Flag();
static Integer iflag = new Integer(0);
static ArrayList<Integer> list = new ArrayList<>();
static Thread t2 = new Thread(() -> {
System.out.println("before wait " + System.currentTimeMillis());
// synchronized(flag) {
// System.out.println(flag.get());
// }

// synchronized(iflag) {
// while (iflag == 0) {
// try {
// iflag.wait();
// } catch (InterruptedException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
// }
// System.out.println(iflag);
// }

synchronized(list) {
while (list.size() == 0)
try {
list.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

System.out.println(list.size());
}
System.out.println("after wait " + System.currentTimeMillis());


});

static final Thread t1 = new Thread( () -> {
try {

Thread.sleep(10000);
// synchronized(flag) {
// flag.change();
// }

// synchronized(iflag) {
// iflag = 1;
// iflag.notify();
// }

synchronized(list) {
list.add(1);
list.notify();
}

} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
});

static void change() {
t1.setDaemon(true);
t1.start();
}

static void waitAndGet() {
t2.setDaemon(true);
t2.start();
}

public static void main(String[] args) {
change();
waitAndGet();

try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}



0 0