2015-11-03 113 views
0

我有一個名爲MyRunnable類:爲什麼此同步方法無法按預期工作?

public class MyRunnable extends Main implements Runnable { 
    String name; // name of thread 
    Thread t; 

    MyRunnable (String threadname) { 
     name = threadname; 
     t = new Thread(this, name); 
     t.start(); 
    } 

    public void run() { 
     try { 
      for (int i=0;i<100000;i++) { 
       extend(1); 
      } 
     } catch (InterruptedException e) { 
      System.out.println("Thread interrupted."); 
     } 
     System.out.println("Thread " + name + " exiting."); 
    } 

} 

和一個名爲Main類:

public class Main { 
    private static List<Integer> numbers=new ArrayList<>(); 

    public synchronized void extend (int i) throws InterruptedException { 
     numbers.add(i); 
    } 
    public synchronized static int getSize() { 
     return numbers.size(); 
    } 

    public static void main(String[] args) { 
     MyRunnable t0=new MyRunnable("0"); 
     MyRunnable t1=new MyRunnable("1"); 
     MyRunnable t2=new MyRunnable("2"); 

     try { 
      t0.t.join(); 
      t1.t.join(); 
      t2.t.join(); 
     } catch (InterruptedException e) { 

     } 
     System.out.println(getSize()); 
    } 
} 

現在我會期望得到30萬作爲輸出,而是我得到一個隨機數(約之間250000和290000),儘管我確實使用了同步方法。我沒看過oracle的文檔http://docs.oracle.com/javase/tutorial/essential/concurrency/syncmeth.html,但我似乎無法弄清楚爲什麼這不能按預期工作。有人能解釋我爲什麼嗎?

預先感謝

+1

您正在創建三個'MyRunnable'實例。每個都在同步。 –

回答

1

方法被同步到調用它們的對象。您需要創建一個在每個對象之間共享的對象,並讓它們在該對象上同步。

private static List<Integer> numbers=new ArrayList<>(); 
public synchronized void extend (int i) throws InterruptedException { 
    synchronize(numbers) { 
     numbers.add(i); 
    } 
} 
1

​​這裏鎖定抵靠該方法extend被調用的對象(因爲它是一個實例方法)。因此,您正在同步三個不同的對象。

如果您在共享的static列表中同步(例如),則會得到預期的結果。

相關問題