2013-02-24 88 views
-1

在下面的代碼中,如果我同步bar方法,它在輸出方面沒有什麼不同 - 我做錯了什麼?我相信同步「欄」會使「ThreaOne」被打印10次,然後只打印「ThreadTwo」將開始,但事實並非如此。我得到的輸出中如下:簡單的線程同步問題


 
I am Test thread:Thread OneOneOneOne 
I am Test thread:Thread OneOneOneOne 
I am Test thread:Thread OneOneOneOne 
I am Test thread:Thread OneOneOneOne 
I am in main now 
I am Test thread:Thread OneOneOneOne 
I am Test thread:Thread Two 
I am Test thread:Thread Two 
I am Test thread:Thread OneOneOneOne 
I am Test thread:Thread Two 
I am Test thread:Thread OneOneOneOne 
I am Test thread:Thread Two 
I am Test thread:Thread OneOneOneOne 
I am Test thread:Thread Two 
I am Test thread:Thread OneOneOneOne 
I am Test thread:Thread Two 
I am Test thread:Thread OneOneOneOne 
I am Test thread:Thread Two 
I am Test thread:Thread Two 
I am Test thread:Thread Two 
I am Test thread:Thread Two 
I am in main now 

等。這裏是我的代碼:

package com.rahul; 

class ThreadTest implements Runnable{ 
    @Override 
    public void run() { 
     bar(); 
    } 
    public synchronized void bar() { 
     for(int i=0;i<10;i++){ 
      System.out.println("I am Test thread:"+Thread.currentThread().getName()); 
      try { 
       Thread.sleep(1000); 
      } catch (InterruptedException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 
     } 

    } 
} 

public class Test{ 
    public static void main(String[] args) { 
     Thread t1 = new Thread(new ThreadTest(),"Thread OneOneOneOne"); 
     Thread t2 = new Thread(new ThreadTest(),"Thread Two"); 
     t1.start(); 
     try{ 
      Thread.sleep(4000); 
     } catch (InterruptedException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 

     t2.start(); 
     while(true){ 
      System.out.println("I am in main now"); 
      try { 
       t2.join(); 
       Thread.sleep(4000); 
      } catch (InterruptedException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 
     } 
    } 
} 

回答

3

你有兩個實例ThreadTest。他們沒有任何關係,你不調用同一個bar()

如果你這樣做,而不是:

ThreadTest tt = new ThreadTest(); 
Thread t1 = new Thread(tt,"Thread OneOneOneOne"); 
Thread t2 = new Thread(tt,"Thread Two"); 

然後兩個線程共享的ThreadTest一個實例,並只有一個線程將能夠在一個時間打電話bar()單個實例。

+0

該死的,我錯過了。非常感謝Brian! – user1291291 2013-02-24 07:32:35

2

聲明該方法爲​​不會產生您所期望的效果。每個線程在它自己的實例ThreadTest上同步,因此這些調用不會相互影響。您需要在共享對象上同步一個線程才能阻止另一個線程。例如:

class ThreadTest implements Runnable{ 
    private static Object LOCK_OBJECT = new Object(); 
    @Override 
    public void run() { 
     bar(); 
    } 
    public void bar() { 
     synchronized (LOCK_OBJECT) { 
      for(int i=0;i<10;i++){ 
       System.out.println("I am Test thread:"+Thread.currentThread().getName()); 
       try { 
        Thread.sleep(1000); 
       } catch (InterruptedException e) { 
        // TODO Auto-generated catch block 
        e.printStackTrace(); 
       } 
      } 
     } 
    } 
} 
0

你同步是由只有一個線程訪問,因爲它們是實例方法,所以每個線程是調用它的自己杆法的方法。

也許你想聲明欄方法爲static