2013-04-22 45 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