2013-04-24 55 views
0

我对这个主题的最后一个问题和相应的答案没有解释所有细节。所以,我决定简化代码:同步工作线程使用的共享对象

List<String> wis = new ArrayList<String>(); 
for(int i=0;i<3000;i++) { 
    wis.add("test_" + i); 
} 
DayCalc calc = new DayCalc(); 
List<List<String>> partition = MyPartition.partition(wis, 30); 
ExecutorService executor = Executors.newFixedThreadPool(4); 
for(List<String> part: partition) { 
    Runnable worker = new DayCalcWorker(part, calc); 
    executor.execute(worker); 
} 
executor.shutdown(); 
while (!executor.isTerminated()) { 
    // Execute all Threads 
} 

共享类对象 “钙” 被所有执行的线程:

public class DayCalc { 
    private static int CURRENT_DAY_OF_YEAR = DateTimes.getCurrentCalendarDay(); 
    ArrayList<String> kwContentArray; 

    public DayCalc() { 
     kwContentArray = new ArrayList<String>(); 
    } 

    private int getCurrentCalendarDay(Calendar cal) { 
     // Reset time to start of day (00:00) 
     cal.set(Calendar.HOUR, 0); 
     cal.set(Calendar.MINUTE, 0); 
     // Get starting day 
     Calendar currentTime2 = StartDate.getStartDate(); 
     System.out.println("Day: " + CURRENT_DAY_OF_YEAR); 
     System.out.println("Start Date: " + currentTime2.getTime()); 
     int day = (int) Convert.daysBetween(currentTime2.getTime(), cal.getTime()); 
     return day; 
    } 

    public void setValueFromWorkItem(String wiID, String duration, Calendar cal) { 
     if (duration != null) { 
     this.setDurationValues(wiID, duration, cal); 
     } else { 
     int currentDay = getCurrentCalendarDay(cal); 
     long time = 0; 
     kwContentArray.add(String.valueOf(time)); 
     } 
    } 

    // [...] 
} 

线程Worker类:​​

public class DayCalcWorker implements Runnable { 

    private List<String> wis; 
    private DayCalc dayCalc;  
    GregorianCalendar cal = new GregorianCalendar(); 
    GregorianCalendar cal2 = new GregorianCalendar();  

    public DayCalcWorker(List<String> wis, DayCalc dayCalc) { 
     this.wis = wis; 
     this.dayCalc = dayCalc; 
    }  

    @Override 
    public void run() { 
     if (wis != null && wis.size() > 0) { 
      for(String wi: wis) { 
      long randomDate = System.currentTimeMillis() + Random.getValue(); 
      cal.setTime(new Date(randomDate)); 
      dayCalc.setValueFromWorkItem(wi, "24", cal); 
      } 
     } 
    } 
} 

问题

是否保存不是以同步方法setValueFromWorkItemgetCurrentCalendarDay,因为它们使用例如从每个工作线程只有一个本地创建的日历对象

因为从对象calcDayCalc是共享的,我只有继续照顾它们在该类别中创建并且不与从中调用的方法calc工作线程传递的对象的对象,不是吗?

请注意,代码本身根本没有意义。它应该解释我使用需要同步(可能)的可变日历对象。

回答

1

不,这不安全。您正在修改setValueFromWorkItem()方法中的共享列表(kwContentArray)。因此,此修改以及对此共享列表的所有其他访问(读取或写入)必须进行同步。如果符合您的需求,您也可以使用并发List实现。

+0

好的,在每个线程中创建的GregorianCalendar对象是什么? – sk2212 2013-04-24 09:48:26

+0

它们对于每个线程都是本地的,因此它们不需要以同步方式访问。 – 2013-04-24 09:49:10