2015-10-16 89 views
0

我想在幾個線程(6)之間同步一個int計數器。以下是我的工人班。我想我的私人領域countertest同步:Java在執行程序服務池中的線程之間同步數據

public class DbWorker implements Callable { 

    private final Object lock = new Object(); 
    private int countertest = 0 ; 

    private boolean IsActive(Integer act) 
    { 
     synchronized(lock){ 
     boolean exists = false; 
     countertest++; 
      .... 
     System.out.println("countertest IS : " + countertest); 
     } 
     return true; 
    } 

    public void run() { 
     .... 
     IsActive(act): 
     ... 
    } 

} 

在我的主類我使用for循環和ExecutorService的創建線程。請看下面:

private ExecutorCompletionService<Integer> _objQueue ; 

for(int j = 0; j < 6; j++){ 
    _objQueue.submit(new DbWorker("SOME PARAMETER" , _snapshots.get(j) , j) ); 
} 

我countertest變量沒有同步它打印不同的數字(非順序)。我究竟做錯了什麼?

+0

「重複」,國際海事組織,是一個壞的問題,一個不好的答案。不好的,因爲它促進了對象可以是「靜態」或不靜態的想法。 (他們不能:只有_variables_可以是靜態的或不是靜態的。)而且,不好的,因爲它促進了'靜態'在鎖定方面的不同。 (事實並非如此,重要的是,兩個線程不能同時鎖定同一個對象,'synchronized'語句是從靜態變量,非靜態變量還是通過調用方法獲取引用是不相關)。 –

回答

3

你鎖

private final Object lock = new Object(); 

是一個實例字段。換句話說,每個DbWorker對象都有一個。

你然後提交DbWorker實例來執行

_objQueue.submit(new DbWorker("SOME PARAMETER" , _snapshots.get(j) , j) ); 

每個線程都有自己的DbWorker,因此自己的鎖。線程永遠不會與任何其他線程競爭。

創建一個DbWorker並在線程中共享它,即。 submit每次都一樣DbWorker實例。

+0

我正在爲每個DbWorker傳遞一個參數。我不能使用相同的DbWorker。 –

+0

@KennerDev然後分享計數器和它們之間的鎖。如果有的話,使用「AtomicInteger」。 –

+0

我的鎖已經是最終的了,我還需要做什麼? –

2

因爲您在循環中創建一個實例,其中countertestlock是實例變量,因此每個對象都會得到一個新實例。

  1. countertest將始終是1在這種情況下,它不是實例

  2. 多個線程不獲取相同的鎖,所以它是無用之間共享。

+0

我正在爲每個DbWorker傳遞一個參數。我不能使用相同的DbWorker。 –

+0

我只是回答你的問題,「爲什麼它不工作」。我不知道你想做什麼,但是你的代碼看起來很破碎 –