以下代码从大型列表中创建任务,并将其拆分为子列表(列表l):
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
}
工作线程的示例代码:
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
的对象被所有线程用作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);
}
}
}
问题:
是否真的需要从共享setValueFromItem
实例同步KwArrayDuration
功能?
我想是的,因为如果调度程序停止,结果可能会有所不同在这一行之后
int currentDay = getCurrentCalendarDay(cal);
和另一个线程使用此int值进一步逻辑。
答案 0 :(得分:0)
您需要synchronize
如果持续时间是可变的并且是共享的,或者如果在其他线程之间共享cal,则调用getCurrentCalendarDay(cal)
会导致与进入方法时所期望的结果不同。这也适用于duration
如果它是可变的&amp;共享。
如果共享kwContentArray
,您还需要同步。
故事的道德,是同步访问所有共享的可变数据。