2015-12-02 216 views
2

我無法理解lockswait方法和notify方法如何工作。暫停和取消暫停線程

所以據我所知,如果在線程上調用x.wait(),它會等到另一個線程調用x.notify()。從此以後,一切都會順利進行。我的代碼應該做的只是在線程中打印i,然後暫停並等待,直到線程被通知。但是有些事情出錯了。我使用了錯誤的鎖嗎?

class X { 
     private Thread thread; 
     private boolean isPaused; 

     public X() { 
      isPaused = false; 

      this.thread = new Thread(new Runnable() { 
       @Override 
       public synchronized void run() { 
        for (int i = 0; i < 10; i++) { 
         System.out.println(i); 
         pause(); 
         waitTillUnpaused(); 

        } 
       } 
      }); 

      System.out.println("Starting the thread"); 
      this.thread.start(); 


      unpause(); 

      waitTillPaused(); 
      unpause(); 

      waitTillPaused(); 
      unpause(); 

      waitTillPaused(); 
      unpause(); 

      waitTillPaused(); 
      unpause(); 

      waitTillPaused(); 
      unpause(); 

      System.out.println("End"); 
     } 

     public void waitTillUnpaused() { 
      synchronized (thread) { 
       try { 
        while (isPaused) { 
         thread.wait(); 
        } 
       } catch (Exception e) { 
        e.printStackTrace(); 
       } 
      } 
     } 

     public void pause() { 
      synchronized (thread) { 
       isPaused = true; 
      } 
     } 

     public void waitTillPaused() { 
      synchronized (thread) { 
       while (!isPaused) { 
       } 
      } 
     } 

     public void unpause() { 
      synchronized(thread){ 
       isPaused = false; 
       thread.notifyAll(); 
      } 
     } 
    } 
+0

你忘記在'waitTillPaused'中調用'wait'。你只需按住鎖並旋轉,使任何其他線程都無法暫停你。 (另外,如果你想等到你暫停,那麼'暫停'也必須調用'notifyAll'。) –

回答

0

是的,你使用了錯誤的鎖。更改代碼:

private volatile boolean isPaused; 
... 
    public void waitTillPaused() { 
      while (!isPaused) { 
      } 
    } 

以下幾點:

public void pause() { 
     synchronized (thread) { // lock thread 
      isPaused = true; 
     } 
    } 

    public void waitTillPaused() { // lock thread 
     synchronized (thread) { 
      while (!isPaused) { 
      } 
     } 
    } 

方法waitTillPaused鎖定線程,方法pausewait解鎖永遠,這是一個死循環。當你使用它wait解鎖線程,但如果您使用以下命令:

synchronized (thread) { 
     while (!isPaused) { 
     } 
} 

線程不會被解鎖的。