Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 有人能解释为什么这个程序显示非法监视器状态异常吗?_Java_Multithreading_Exception_Parallel Processing_Illegalmonitorstateexcep - Fatal编程技术网

Java 有人能解释为什么这个程序显示非法监视器状态异常吗?

Java 有人能解释为什么这个程序显示非法监视器状态异常吗?,java,multithreading,exception,parallel-processing,illegalmonitorstateexcep,Java,Multithreading,Exception,Parallel Processing,Illegalmonitorstateexcep,我打算通过这个程序将数字打印到49,然后等待字母线程完成字母打印,然后控件返回到数字线程并完成执行 但这段代码在打印到49的数字后引发异常,然后打印A-Z,然后无法执行,显示IllegalMonitorStateException 无法执行显示非法监视器状态异常 这是由于调用notify;方法不符合its的要求 唤醒正在该对象监视器上等待的单个线程。 ... 此方法只能由作为的所有者的线程调用 此对象的监视器 这同样适用于等待方法: 此方法只能由作为此对象监视器所有者的线程调用 TL:DR 您在

我打算通过这个程序将数字打印到49,然后等待字母线程完成字母打印,然后控件返回到数字线程并完成执行

但这段代码在打印到49的数字后引发异常,然后打印A-Z,然后无法执行,显示IllegalMonitorStateException

无法执行显示非法监视器状态异常

这是由于调用notify;方法不符合its的要求

唤醒正在该对象监视器上等待的单个线程。 ... 此方法只能由作为的所有者的线程调用 此对象的监视器

这同样适用于等待方法:

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

TL:DR

您在错误的锁上调用wait和notify,即此函数返回的实例的隐式锁

分别将这些调用更改为:

锁定。通知;和锁,等等

基于您的代码运行示例:

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();
    }
}
无法执行显示非法监视器状态异常

这是由于调用notify;方法不符合its的要求

唤醒正在该对象监视器上等待的单个线程。 ... 此方法只能由作为的所有者的线程调用 此对象的监视器

这同样适用于等待方法:

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

TL:DR

您在错误的锁上调用wait和notify,即此函数返回的实例的隐式锁

分别将这些调用更改为:

锁定。通知;和锁,等等

基于您的代码运行示例:

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();
    }
}