2013-04-22 78 views
0

下面的代碼創建從一個大名單,其被分成子列表(表L)任務:線程中的共享變量 - >需要同步它們嗎?

public class MainReadingTask implements Runnable { 

private KwArrayDuration duration; 
private List<Item> wis; 

    public MainReadingTask(List<Item> wis, KwArrayDuration duration) { 
     this.wis = wis; 
     this.duration = duration; 
    } 

    @Override 
    public void run() { 
    try { 
     for (Item wi : wis) { 
     duration.setValueFromItem(wi.getId(), null, cal); 
     } 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
    } 

} 

的類的對象KwArrayDuration是:工作線程的

 ExecutorService executor = Executors.newFixedThreadPool(cpu); 
     KwArrayDuration duration = new KwArrayDuration(); 
     for (List<Item> l : partition) { 
      Runnable readingTask = new MainReadingTask(l, duration); 
      executor.execute(readingTask); 
     } 
     executor.shutdown(); 
     while (!executor.isTerminated()) { 
      // Execute all Threads 
     } 

示例代碼被所有線程用作storage類,它將每個任務的結果插入到數組列表中(kwContentArray)。

此外,類KwArrayDuration包含一些方法來計算一些東西。這些方法是由每個工作線程調用:

public synchronized void setValueFromItem(String id, DurationTime duration, Calendar cal) { 
    if(duration != null) { 
    try { 
     this.setDurationValues(id, duration, cal); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
    } else { 
    int currentDay = getCurrentCalendarDay(cal); 
    long time = 0; 
    for (int i = currentDay; i < kwContentArray.size(); i++) { 
     KwArrayWrapper currentDayKW = kwContentArray.get(i); 
     currentDayKW.setValues(wi, String.valueOf(time)); 
     kwContentArray.set(i, currentDayKW); 
    } 
    } 
} 

問:

是否真的需要從同步共享KwArrayDuration例如setValueFromItem功能? 我想是的,因爲如果調度程序停止了,結果可能會有所不同。在此行之後

int currentDay = getCurrentCalendarDay(cal); 

另一個線程將此int值用於進一步的邏輯。

回答

0

有你需要synchronize

  1. 兩個原因,如果持續時間是可變的,共享的,或者如果卡被其他線程之間共享,然後調用getCurrentCalendarDay(cal)可能導致然後不同的結果發生了什麼當進入方法預期。這也適用於duration如果它是可變的&共享。

  2. 如果共享kwContentArray,則還需要進行同步。

道德故事,是同步訪問所有共享的可變數據。

+0

好的......「cal」是在每個線程的構造函數中創建的,如下所示:GregorianCalendar cal = new GregorianCalendar();還需要同步? – sk2212 2013-04-23 07:31:55

+0

如果cal一次可以被多個線程訪問和修改,那麼是的。不是字段cal,而是cal.set(Calendar.YEAR,10)。因爲cal是可變的,所以你通過setter – 2013-04-23 12:16:29

+0

碰到數據競賽嗯,好的...我會創建一個新的問題,因爲你的回答在所有細節上都不能回答我的問題。無論如何,我會接受你的答案,並創建更多可理解的代碼。 – sk2212 2013-04-24 09:08:20