线程等待时发生Mass IllegalMonitorStateException

时间:2013-03-20 22:14:46

标签: java multithreading wait runnable illegalstateexception

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

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

使用这段代码

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

在这种情况下,obj param会成为跑步者 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();
        }   
    }
}

1 个答案:

答案 0 :(得分:2)

如上所述,您必须握住您呼叫wait() / notify()的对象的监视器。由于您在runner上调用这些方法,因此这些说明必须位于

synchronized(runner) {

块。

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

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