【问题标题】:Can anybody explain why this program is showing an IllegalMonitorStateException?谁能解释为什么这个程序显示 IllegalMonitorStateException?
【发布时间】:2021-05-13 21:20:11
【问题描述】:
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 个数字,然后等到 Letters 线程完成打印字母,然后控制返回到 Numbers 线程并完成执行。

但此代码在打印最多 49 的数字后抛出异常,然后打印 A-Z,然后 执行失败并显示 IllegalMonitorStateException

【问题讨论】:

    标签: java multithreading exception parallel-processing illegalmonitorstateexcep


    【解决方案1】:

    执行失败并显示 IllegalMonitorStateException。

    这是因为对 notify(); 方法的调用不服从其 contract: 的事实

    唤醒正在此对象的监视器上等待的单个线程。 (...) 这个方法只能被拥有的线程调用 此对象的监视器。

    同样适用于wait 方法:

    该方法只能由作为该对象监视器所有者的线程调用。

    TL:DR

    您在错误的上调用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();
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2013-04-16
      • 2017-09-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-10-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多