2013-11-28 72 views
0

我有2個線程t1和t2,它將打印1到10. t1線程將打印奇數,而t2線程將打印偶數。我很困惑,我怎麼會知道這個線程是t1或t2,並且打印1到10應該按順序完成。我最終這樣做了。請建議我是哪裏出錯了。等待並通知2個並行運行線程

class Print implements Runnable{ 

Object odd = new Object(); 

public void run() { 
    for (int i = 1; i <= 10; i ++){ 

     if(Thread.currentThread().getName().equals("t1")){ 
      synchronized(odd){ 
        if ((i %2 !=0)) 
        System.out.println(i + " Thread - " + Thread.currentThread().getName()); 

       try { 
        odd.wait(); 
       } catch (InterruptedException e) { 
        e.printStackTrace(); 
       } 
      } 
     } 

     if(Thread.currentThread().getName().equals("t2")){ 
     synchronized(odd){ 
        if ((i %2 ==0)){ 
        System.out.println(i + " Thread - " + Thread.currentThread().getName()); 
        odd.notifyAll(); 
       } 
      } 
     } 

    } 

} 

} 

public class EvenOdd { 

    public static void main(String[] args) { 

      Print obj1 = new Print(); 
      Print obj2 = new Print(); 

      Thread t1 = new Thread(obj1, "t1"); 
      Thread t2 = new Thread(obj2, "t2"); 
      t1.start(); 
      t2.start(); 

     } 

    } 

輸出:

1螺紋 - T1 2螺紋 - T2 4螺紋 - T2 6螺紋 - T2 8螺紋 - T2 10螺紋 - T2

+0

如果你期望按順序行事,那你爲什麼需要線程? –

+0

這不是關於順序,但我如何控制兩個並行運行線程的執行以打印1到10. t1打印1並等待t2打印2,然後t1打印3等等。希望你明白我的觀點。謝謝 – Rajat

回答

0

有沒有真正的同步在線程之間。每個使用不同的鎖(即它是自己的「奇怪」成員副本)。

另外,在您的實現中,沒有什麼能夠阻止第二個線程打印所有偶數並快速完成其循環。它從不等待線程#1。

+0

謝謝Eyal指出確切的錯誤。 – Rajat

0

不要新建兩個Print您的odd不共享。
我改變你的代碼,它的工作原理如你預期:

class Print implements Runnable{ 
     Object odd = new Object(); 

     public void run() { 
     for(int i=1;i<=10;i++){ 
     if(Thread.currentThread().getName().equals("t1")){ 
      synchronized(odd){ 
      if(i%2==0) 
       continue; 
      System.out.println(i + " Thread - " + Thread.currentThread().getName()); 
      odd.notifyAll(); 
      odd.wait(); 
      } 
     }else{ 
      synchronized(odd){ 
      if(i%2!=0) 
       continue; 
      System.out.println(i + " Thread - " + Thread.currentThread().getName()); 
      odd.notifyAll(); 
      odd.wait(); 
      } 
     } 
     } 
     } 
    } 

主要代碼:

Print obj1 = new Print() 
    Thread t1 = new Thread(obj1, "t1") 
    Thread t2 = new Thread(obj1, "t2") 
    t1.start(); 
    Thread.sleep(10) //let t1 run first 
    t2.start(); 
+0

謝謝Fairjm。現在我明白我正在使用兩個不同的鎖副本,因此兩個線程獨立運行,產生意外的行爲。再次感謝您的幫助。 – Rajat

0

你需要鎖定同一個對象。或者讓你的鎖對象static(這不好,順便說一句)。可能所有同步邏輯都應在main方法上完成,並從Print類中排除。

+0

感謝Mytitle的解釋。還有一個問題。爲什麼你說靜態鎖不好,爲什麼我應該同步在主?請解釋。提前致謝。 – Rajat

0

如果按照代碼的順序執行某些操作,那麼它就不是線程的候選對象。線程只有在某些事情可以並行完成時纔有所幫助,所以在你的情況下i.E.如果你不關心打印數字的順序。