Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 同步工作线程使用的共享对象_Java_Multithreading_Calendar_Synchronization - Fatal编程技术网

Java 同步工作线程使用的共享对象

Java 同步工作线程使用的共享对象,java,multithreading,calendar,synchronization,Java,Multithreading,Calendar,Synchronization,我对这个话题的最后一个问题和相应的答案并没有解释所有细节。因此,我决定简化代码: 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.parti

我对这个话题的最后一个问题和相应的答案并没有解释所有细节。因此,我决定简化代码:

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
}
List wis=new ArrayList();
对于(int i=0;i 0){
用于(字符串wi:wis){
long randomDate=System.currentTimeMillis()+Random.getValue();
校准设置时间(新日期(随机日期));
dayCalc.setValueFromWorkItem(wi,“24”,cal);
}
}
}
}
问题

同步方法
setValueFromWorkItem
getCurrentCalendarDay
是否保存not,因为它们仅使用来自每个工作线程的本地创建的日历对象

因为类
DayCalc
中的对象
calc
是共享的,所以我只需要关心在这个类中创建的对象,而不是调用
calc
方法的工作线程传递的对象,不是吗


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

不,这不安全。您正在从
setValueFromWorkItem()
方法内部修改共享列表(
kwContentArray
)。因此,此修改以及对该共享列表的所有其他访问(读或写)必须同步。如果符合您的需要,您还可以使用并发列表实现。

好的,那么在每个线程中创建的GregoriaCalendar对象是什么呢?它们是每个线程的本地对象,因此不需要以同步方式访问它们。
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));
       }
    }

  // [...]
}
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);
           }
       }
    }
}