2013-04-24 51 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