2013-03-20 54 views
0

當過我打電話pauseThread()它總是拋出拋出:IllegalMonitorStateException。大衆拋出:IllegalMonitorStateException上線等待

我注意到,我需要自己的對象監視器能夠導致線程等待的文件中。

與這段代碼

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

在這種情況下將在OBJ PARAM是轉輪 的同時(ServerTickHandler.peakBlockDestructionQueue()== NULL){} 但當obj.wait();被稱爲是否需要通知?或將它通知本身時,同時條件不爲真 將同步(){}碼塊連續地循環或將它仍然需要內的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(); 
     } 
    } 
} 

回答

2

類如記錄,你一定要挺住,你叫wait()/notify()對象的監視器。由於您在runner上調用這些方法,因此這些說明必須位於

synchronized(runner) { 

塊中。

也就是說,在線程上調用wait()/notify()是一個很奇怪的選擇。你最好使用最後的專用鎖對象來等待/通知。你的程序還有其他不好的選擇。例如,從構造函數初始化靜態字段。

wait()notify()非常低的水平,很難使用原語。您應該使用像Locks,Semaphores,CountDownLatches,BlockingQueues等更高級別的抽象。

+0

謝謝你,它現在的工作。 – JohnM 2013-03-20 23:34:22