Search code examples
javamultithreadingarraylistconcurrency

how to use Multithreading With ArrayList in Java


I have a program that works perfectly, unfortunately I have some calculations that takes a lot of time, some minutes.

My objective is to use multithreading to accelerate the parts that take so much time.

In this example I give the prototype of the part that I should parallelize.

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;
}

As you can see the method

public static ArrayList<Object2> createListOfObject2(ArrayList<Object1> mylist)

gets a list of Object1, and should create another list of object2.

I made two for loops, and each time I create an object2 forming by two object, it should take O(n²) time. For bigger list it takes a long time.

So where should I put the multithreading and which type of list should I use?

The second Problem is that the class MyCalculator is a singleton Class, and I create only one object of it, and in my opinion even using multithreading the real program will not benefit of multithreading.

What are the rules I should follow to use multithreading?

Many Thanks.


Solution

  • The fact that your object is a singleton is irrelevant. What matters is shared mutable state. So, if your computation don't mutate shared state, and every computation is thus independant from the others, you can just use a parallel stream:

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