如何在Java中与ArrayList一起使用多线程

如何在Java中与ArrayList一起使用多线程,java,multithreading,arraylist,concurrency,Java,Multithreading,Arraylist,Concurrency,你好, 我有一个程序运行得很好,不幸的是,我有一些计算需要很多时间,几分钟 我的目标是使用多线程来加速那些花费大量时间的部分 在这个例子中,我给出了我应该并行化的部件的原型 public static ArrayList<Object2> createListOfObject2(ArrayList<Object1> mylist) { ArrayList<Object2> listToReturn = new ArrayList<>();

你好,

我有一个程序运行得很好,不幸的是,我有一些计算需要很多时间,几分钟

我的目标是使用多线程来加速那些花费大量时间的部分

在这个例子中,我给出了我应该并行化的部件的原型

public static ArrayList<Object2> createListOfObject2(ArrayList<Object1> mylist) {
    ArrayList<Object2> listToReturn = new ArrayList<>();
    Object2 object2;
    for (int i = 0; i < mylist.size(); i++) {
        for (int j = 0; j < mylist.size(); j++) {
            object2 = heavyCalcul(mylist, i, j);
            listToReturn.add(object2);
        }
    }
    return listToReturn;
}
private static Object2 heavyCalcul(ArrayList<Object1> mylist, int i, int j) {
    int weight = MyCalculator.getInstance().calcul(mylist.get(i),mylist.get(j));
    Object2 Object2 = new Object2(weight);
    return Object2;
}
公共静态ArrayList CreateListofObject 2(ArrayList mylist){
ArrayList listToReturn=新建ArrayList();
对象2对象2;
对于(int i=0;i
正如你所看到的,这个方法

public static ArrayList<Object2> createListOfObject2(ArrayList<Object1> mylist)
公共静态ArrayList CreateListofObject 2(ArrayList mylist)
获取Object1的列表,并应创建另一个object2列表

我做了一个twoo foor循环,每次我创建一个由两个对象组成的object2时,它应该花费O(n²)次

对于较大的列表,这需要很长时间

那么我应该把我应该使用的多线程和wich类型的列表放在哪里呢

第二个问题是MyCalculator类是一个单例类,我只创建了它的一个对象,在我看来,即使在实际程序中使用multhitreding,也不会从multhitreding中受益

我使用Multhitreding应该遵循哪些规则


非常感谢。

您的对象是单体的事实与此无关。重要的是共享可变状态。因此,如果您的计算不改变共享状态,并且每个计算都与其他计算无关,那么您可以使用并行流:

myList.parallelStream()
      .flatMap(first -> myList.stream().map(second -> MyCalculator.getInstance().calcul(first, second)))
      .collect(Collectors.toList());

我正要提出这个建议,但我不同意单身是无关紧要的。若它有内部状态,那个么该状态必须被保护,然后添加更多线程可能不会有帮助,或者会导致bug。如果它没有内部状态(希望没有,因为它是作为单例对象创建的!),它是安全的;那么选项是什么呢?即使是Singleton对象,如果两个不同的对象调用同一个方法,它们的执行都是独立的,除非它们有一些共享字段。原因是不同的线程有不同的方法堆栈,但字段存储在内存中。另外,在使用parallelStream之前要注意一点。parallelStream使用的线程数在jvm中共享,即它们具有公共线程池。因此,可以使用并行流进行计算,但如果计算涉及网络调用,则应避免使用并行流,因为它会阻塞线程,并且下一个请求将处于等待状态,直到这些任务结束。@zakzak如果计算没有改变共享状态,您不会有任何问题。在这个阶段,订单并不重要。