【问题标题】:Mass IllegalMonitorStateException on thread wait线程等待时出现大量 IllegalMonitorStateException
【发布时间】:2023-03-13 15:41:02
【问题描述】:

当我调用 pauseThread() 时,它总是抛出 IllegalMonitorStateException。

我在文档中注意到我需要拥有对象监视器才能使线程等待。

用这段代码

synchronized (obj) {
         while (<condition does not hold>)
             obj.wait();
         ... // Perform action appropriate to condition
     }

在这种情况下,obj 参数会是 runner while(ServerTickHandler.peakBlockDestructionQueue() == null){} 但是当 obj.wait();被称为是否需要通知?还是当while条件不成立时它会通知自己 synchronized (){} 代码块会持续循环还是需要在 synchronized (){} 中的 while 循环来完成此操作?

编辑:syncronized(){} 会通过 run 方法进入吗?

这是我的课

public class ServerTickSaveHandler implements Runnable
{
    private static Thread   runner;
    /**
     * Creates a new thread for dealing with logging block destruction when using certain tools.
     * @param threadName Name of the thread.
     */
    public ServerTickSaveHandler(String threadName)
    {
        runner = new Thread(this, threadName);
    }
    /**
     * If thread has nothing to do we shall pause it so it does not needlessly run :D.
     * @throws InterruptedException
     */
    public void pauseThread()
    {
        try
        {
            runner.wait();
        }
        catch (InterruptedException e)
        {
            e.printStackTrace();
        }
        catch(IllegalMonitorStateException e)
        {
            e.printStackTrace();
        }
    }
    /**
     * If Items from DropItemQueue need ticking lets resume this thread.
     * @throws IllegalMonitorStateException
     */
    public void resumeThread()
    {
        try
        {
            runner.notify();
        }
        catch (IllegalMonitorStateException e)
        {
            e.printStackTrace();
        }
    }
    /**
     * The thread that is spawned when this object is created.
     */
    public void run()
    {
        while (true)
        {
            // long start = System.currentTimeMillis();

            WorldData worldData = ServerTickHandler.getBlockDestructionQueue();
            if (worldData != null)
            {
                worldData.saveToFile();
            }
            else pauseThread();

            // long end = System.currentTimeMillis();

            // NumberFormat formatter = new DecimalFormat("#0.00000");
            // Utils.log("Save Tick Handler Execution time is " +
            // formatter.format((end - start) / 1000d) + " seconds");
        }
    }
    /**
     * Starts the thread.
     * @throws IllegalStateException
     */
    public void startThread()
    {
        try
        {
            runner.start();
        }
        catch (IllegalStateException e)
        {
            e.printStackTrace();
        }   
    }
}

【问题讨论】:

    标签: java multithreading wait runnable illegalstateexception


    【解决方案1】:

    如文档所述,您必须持有您调用wait()/notify() 的对象的监视器。由于您在 runner 上调用这些方法,因此这些说明必须在

    synchronized(runner) {
    

    阻止。

    也就是说,在线程上调用wait()/notify() 是一个相当奇怪的选择。您最好使用最终的专用锁定对象来等待/通知。您的程序中还有其他不好的选择。例如,从构造函数初始化静态字段。

    wait()notify() 是非常低级的,难以使用的原语。您应该使用更高级别的抽象,例如 Locks、Semaphores、CountDownLatches、BlockingQueues 等。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-10-30
      • 2016-08-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-04
      • 2023-03-28
      相关资源
      最近更新 更多