有人能解释为什么这个程序显示一个IllegalMonitorStateException吗?


class Lock 
{
public int l=0;
}
class Numbers extends Thread
{
final Lock lock;
Numbers(Lock l,String name)
{
super(name);
lock=l;
}

public void run()
{
synchronized(lock)
{
for(int i=0;i<100;i++)
{
if(i==50)
{
try
{
while(lock.l==0)
{
System.out.println("Waiting for letters to complete");
wait();
System.out.println("Wait complete");
}
}
catch(InterruptedException e)
{
System.err.println("ERROR");
}
}
System.out.println(i);
}
}
}
}
class Letters extends Thread
{
final Lock lock;
Letters(Lock l,String name)
{
super(name);
lock=l;
}

public void run()
{
synchronized(lock)
{
for(int i=65;i<=90;i++)
System.out.println((char)i);
lock.l=1;
notify();
}
}
}
public class MyClass
{
public static void main(String args[])
{
Lock l=new Lock();
Numbers n=new Numbers(l,"Numbers");
Letters let=new Letters(l,"Letters");
n.start();
let.start();
}
}

我想通过这个程序打印到49的数字,然后等待,直到字母线程完成打印字母,然后控制返回到数字线程并完成执行。

但是这段代码在打印数字到49之后抛出异常,然后打印A-Z,然后执行失败显示IllegalMonitorStateException.

执行失败,显示IllegalMonitorStateException.

这是由于对notify();方法的调用没有遵守它的契约:

唤醒一个正在此对象监视器上等待的线程。(…(这个方法应该只被拥有的线程调用

,同样适用于wait方法:

这个方法只能由拥有该对象监视器的线程调用。

TL:博士

您在错误的锁上呼叫waitnotify()()。,实例的隐式锁由this返回

分别将这些调用改为:

lock.notify();lock.wait();

基于代码的运行示例:

class Lock{
public int l=0;
}
class Numbers extends Thread
{
final Lock lock;
Numbers(Lock l,String name){
super(name);
lock=l;
}
public void run() {
synchronized(lock) {
for(int i=0;i<100;i++){
if(i==50){
try {
while(lock.l==0){
System.out.println("Waiting for letters to complete");
lock.wait();
System.out.println("Wait complete");
}
}
catch(InterruptedException e){
System.err.println("ERROR");
}
}
System.out.println(i);
}
}
}
}
class Letters extends Thread {
final Lock lock;
Letters(Lock l,String name)
{
super(name);
lock=l;
}
public void run()
{
synchronized(lock){
for(int i=65;i<=90;i++)
System.out.println((char)i);
lock.l=1;
lock.notify();
}
}
}
class MyClass {
public static void main(String args[]) {
Lock l=new Lock();
Numbers n=new Numbers(l,"Numbers");
Letters let=new Letters(l,"Letters");
n.start();
let.start();
}
}