0

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

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

用这段代码

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

在这种情况下,obj 参数是否会运行 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();
        }   
    }
}
4

1 回答 1

2

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

synchronized(runner) {

堵塞。

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

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

于 2013-03-20T22:22:52.947 回答