Tengo una lista de objetos en Java como mil objetos en una Lista y estoy iterando la Lista para cada objeto y el procesamiento posterior. El mismo procesamiento está sucediendo para todos los objetos. Este enfoque de secuencial toma mucho tiempo para el procesamiento, por lo que quiero lograrlo con el procesamiento paralelo en Java. Verifiqué el framework de ejecutor en Java pero me quedé atrapado en él.

Pensé en un enfoque para implementar mi requisito.

Quiero implementar un número fijo de objetos mínimos que cada subproceso procesará para que cada subproceso haga su trabajo y procese los objetos de manera rápida. ¿Cómo puedo lograr esto? O si hay algún otro enfoque para implementar mi requisito, por favor comparta.

Eg:

Listar objetos = nueva Lista ();

Para (Objeto objeto: objetos) {// Haciendo alguna operación común para todos los Objetos

}

0
SSV 5 may. 2018 a las 15:08

3 respuestas

La mejor respuesta

Puede usar un ThreadPoolExecutor, se encargará del equilibrio de carga. Las tareas se distribuirán en diferentes hilos.

Aquí está un ejemplo:

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class Test {

    public static void main(String[] args) {

        // Fixed thread number
        ExecutorService service = Executors.newFixedThreadPool(10);

        // Or un fixed thread number
        // The number of threads will increase with tasks
        // ExecutorService service = Executors.newCachedThreadPool(10);

        List<Object> objects = new ArrayList<>();
        for (Object o : objects) {
            service.execute(new MyTask(o));
        }

        // shutdown
        // this will get blocked until all task finish
        service.shutdown();
        try {
            service.awaitTermination(Long.MAX_VALUE, TimeUnit.MILLISECONDS);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public static class MyTask implements Runnable {
        Object target;

        public MyTask(Object target) {
            this.target = target;
        }

        @Override
        public void run() {
            // business logic at here
        }
    }
}
3
xingbin 5 may. 2018 a las 12:41

Hay muchas opciones para procesar una lista en paralelo:

Usar una secuencia paralela :

objects.stream().parallel().forEach(object -> {
    //Your work on each object goes here, using object
})

Usar un servicio de ejecutor para enviar tareas si desea usar un grupo con más subprocesos que el grupo de bifurcación:

ExecutorService es = Executors.newFixedThreadPool(10);
for(Object o: objects) {
    es.submit(() -> {
        //code here using Object o...
    }
}

Este ejemplo anterior es esencialmente el mismo que el servicio ejecutor tradicional, ejecutando tareas en subprocesos separados.

Como alternativa a estos, también puede enviar utilizando el futuro completable:

//You can also just run a for-each and manually add each
//feature to a list
List<CompletableFuture<Void>> futures = 
    objects.stream().map(object -> CompletableFuture.runAsync(() -> {
    //Your work on each object goes here, using object
})

Luego puede usar el objeto futures para verificar el estado de cada ejecución si es necesario.

2
ernest_k 5 may. 2018 a las 12:31

Divida la lista en varias sublistas y use subprocesos múltiples para procesar cada sublista en paralelo.

public class ParallelProcessListElements {
    public void processList (int numberofthreads,List<Object>tempList, 
            Object obj, Method method){

                final int sizeofList=tempList.size();
                final int sizeofsublist = sizeofList/numberofthreads;
                List<Thread> threadlist = new ArrayList<Thread>();

                for(int i=0;i<numberofthreads;i++) {
                    int firstindex = i*sizeofsublist;
                    int lastindex = i*sizeofsublist+sizeofsublist;
                    if(i==numberofthreads-1)
                        lastindex=sizeofList;

                    List<Object> subList=tempList.subList(firstindex,lastindex );

                    Thread th = new Thread(()->{
                                try{method.invoke(obj, subList);}catch(Exception e) {e.printStackTrace();}
                            });

                    threadlist.add(th);
                }

                threadlist.forEach(th->{th.start();try{Thread.sleep(10);}catch(Exception e) {}});
    }

}

public class Demo {
    public static void main(String[] args) {

        List<Object> tempList= new ArrayList<Object>();
        /**
         * Adding values to list... For Demo purpose..
         */
        for(int i=0;i<500;i++)
            tempList.add(i);

        ParallelProcessListElements process = new ParallelProcessListElements();
        final int numberofthreads = 5;
        Object obj = new Demo();
        Method method=null;

        try{ method=Demo.class.getMethod("printList", List.class);}catch(Exception e) {}
        /**
         * Method Call...
         */
        process.processList(numberofthreads,tempList,obj,method);
    }

    public void printList(List<Integer>list) {
        /**
         * Business logic to process the list...
         */
        list.forEach(item->{
            try{Thread.sleep(1000);}catch(Exception e) {}
            System.out.println(item);
            });
    }
}

1
jithin 14 abr. 2019 a las 21:59