2017-02-17 147 views
1
  1. 線程t1在wait()被命中後進入死鎖。即使 在t2中有notify()。代碼正陷入僵局。 沒有得到打印聲明 - 「等待釋放後::::」等待並通知Java中的死鎖情況

  2. 我可以看到兩個線程競爭獲取顯示器counterAdd()。所以,我假設通知會起作用。

    package com.java.thread.practice; 
    
        public class WaitAndNotify4 { 
    
         int counter = 0; 
    
         /* 
          CounterAdd() is to be accessed by both t1 and t2. 
          If not synchronized not giving consistent output. 
         */ 
         synchronized int counterAdd(){ 
          return counter++; 
         } 
    
         public static void main(String[] args) throws InterruptedException{ 
    
          // Creating method to call the threads. 
          WaitAndNotify4 andNotify4 = new WaitAndNotify4(); 
          andNotify4.testRaceCondition(); 
    
         } 
    
         private void testRaceCondition() throws InterruptedException { 
    
          // Thread t1 created and launched. 
    
          Thread t1 = new Thread(new Runnable(){ 
           @Override 
           public void run() { 
    
            for(int i=0; i<5; i++){ 
             synchronized(this){ 
             if(i== 1){ 
              System.out.println("Calling wait after count 1"); 
              try { 
              // Assuming that this wait will be resumed by notify in t2. 
    
               wait(); 
               System.out.println("After wait is released :::: "); 
              } catch (InterruptedException e) { 
               // TODO Auto-generated catch block 
               e.printStackTrace(); 
              } 
    
             } 
             } 
             counterAdd(); 
            } 
           } 
          }); 
    
    
          Thread t2 = new Thread(new Runnable(){ 
           @Override 
           public void run() { 
            // TODO Auto-generated method stub 
    
            for(int i=0; i<5; i++){ 
             if(i==2){ 
    
              synchronized(this){ 
               System.out.println("Before releasing the counter :::::"); 
               notify(); 
               System.out.println("After releasing the counter :::::"); 
              } 
    
             } 
             counterAdd(); 
            } 
    
           } 
          }); 
    
    
    
          t1.start(); 
          t2.start(); 
    
          t1.join(); 
          t2.join(); 
    
          System.out.println(" Sum value is found as ::::: "+counter); 
    
         } 
        } 
    
+0

不要對沒有引用的文本使用引號格式。 – EJP

回答

1

正在同步於不同的對象。在對象t1的第一種情況下,在t2的第二種情況下,在方法counterAddandNotify4中。爲了永久鎖定andNotify4,你需要做這樣的事情。

public class Main { 
    private int counter = 0; 

    synchronized int counterAdd() { 
     return counter++; 
    } 

    public static void main(String[] args) throws InterruptedException { 
     Main andNotify4 = new Main(); 
     andNotify4.testRaceCondition(); 
    } 

    private void testRaceCondition() throws InterruptedException { 
     Thread t1 = new Thread(new Runnable() { 
      @Override 
      public void run() { 
       for (int i = 0; i < 5; i++) { 
        synchronized (Main.this) { 
         if (i == 1) { 
          System.out.println("Calling wait after count 1"); 
          try { 
           Main.this.wait(); 
           System.out.println("After wait is released :::: "); 
          } catch (InterruptedException e) { 
           e.printStackTrace(); 
          } 
         } 
        } 
        counterAdd(); 
       } 
      } 
     }); 

     Thread t2 = new Thread(new Runnable() { 
      @Override 
      public void run() { 
       for (int i = 0; i < 5; i++) { 
        if (i == 2) { 
         synchronized (Main.this) { 
          System.out.println("Before releasing the counter :::::"); 
          Main.this.notify(); 
          System.out.println("After releasing the counter :::::"); 
         } 
        } 
        counterAdd(); 
       } 
      } 
     }); 

     t1.start(); 
     t2.start(); 

     t1.join(); 
     t2.join(); 

     System.out.println(" Sum value is found as ::::: " + counter); 
    } 
} 
+0

非常感謝。它解決了問題並清除了這個概念。 如果你還可以對部分內容有所瞭解。 「 我可以看到兩個線程競爭獲取counterAdd()中的監視器,因此,我認爲通知將起作用。」 –

+0

如果它們是參考不同對象的兩個不同線程,counterAdd()應該總是打印10總是沒有同步關鍵字。 –