Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

291
Vistas
Uso de un grupo de subprocesos para agregar a una lista

Estoy tratando de leer un archivo y agregar cada línea a una lista.

Dibujo sencillo explicando el objetivo.

Clase principal -

 public class SimpleTreadPoolMain { public static void main(String[] args) { ReadFile reader = new ReadFile(); File file = new File("C:\\myFile.csv"); try { reader.readFile(file); } catch (IOException e) { e.printStackTrace(); } } }

clase de lector -

 public class ReadFile { ExecutorService executor = Executors.newFixedThreadPool(5);//creating a pool of 5 threads List<String> list = new ArrayList<>(); void readFile(File file) throws IOException { try (BufferedReader br = new BufferedReader(new FileReader(file))) { String line; while ((line = br.readLine()) != "") { Runnable saver = new SaveToList(line,list); executor.execute(saver);//calling execute method of ExecutorService } } executor.shutdown(); while (!executor.isTerminated()) { } } }

Clase de ahorro -

 public class SaveToList<E> implements Runnable{ List<E> myList; E line; public SaveToList(E line, List<E> list) { this.line = line; this.myList = list; } public void run() { //modify the line myList.add(line); } }

Traté de tener muchos subprocesos de ahorro para agregar a la misma lista en lugar de agregar un protector a la lista uno por uno. Quiero usar subprocesos porque necesito modificar los datos antes de agregarlos a la lista. Así que asumo que modificar los datos tomaría algún tiempo. Entonces, poner en paralelo esta parte reduciría el consumo de tiempo, ¿verdad?

Pero esto no funciona. No puedo devolver una lista global que incluya todos los valores del archivo. Quiero tener solo una lista global de valores del archivo. Así que el código definitivamente debería cambiar. Si alguien me puede orientar se lo agradecería mucho.

Aunque agregar uno por uno en un solo subproceso funcionaría, usar un grupo de subprocesos lo haría más rápido, ¿verdad?

over 4 years ago · Santiago Trujillo
2 Respuestas
Responde la pregunta

0

El uso de múltiples subprocesos no acelerará nada aquí.

Usted está:

  • Lectura de una línea de un archivo, en serie.
  • Crear un ejecutable y enviarlo a un grupo de subprocesos
  • El ejecutable luego agrega cosas en una lista

Dado que está utilizando un ArrayList , necesita sincronizar el acceso a él, porque lo está mutando desde varios subprocesos. Entonces, está agregando cosas a la lista en serie.

Pero incluso sin la sincronización, el tiempo necesario para el IO superará con creces el tiempo necesario para agregar la cadena a la lista. Y agregar subprocesos múltiples solo lo ralentizará más, porque está trabajando para construir el ejecutable, enviarlo al grupo de subprocesos, programarlo, etc.

Es más simple perderse todo el paso intermedio:

  • Leer una línea de un archivo, en serie.
  • Agregue la lista a la lista, en serie.

Asi que:

 try (BufferedReader br = new BufferedReader(new FileReader(file))) { String line; while (!(line = br.readLine()).isEmpty()) { list.add(line); } }
over 4 years ago · Santiago Trujillo Denunciar

0

De hecho, debería probar si vale la pena usar subprocesos múltiples en su aplicación, simplemente compare cuánto tiempo lleva leer todo el archivo sin ningún procesamiento en las filas y compárelo con el tiempo que lleva procesar en serie todo el archivo.

Si su proceso no es demasiado complejo, supongo que no vale la pena usar subprocesos múltiples.

Si encuentra que el tiempo que lleva es mucho más, entonces puede pensar en usar uno o más subprocesos para hacer los cálculos.

Si es así, podría usar Future s para procesar lotes de cadenas de entrada o tal vez podría usar una Cola segura para subprocesos para enviar cadenas a otro proceso.

 private static final int BATCH_SIZE = 1000; public static void main(String[] args) throws IOException { BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream("big_file.csv"), "utf-8")); ExecutorService pool = Executors.newFixedThreadPool(8); String line; List<String> batch = new ArrayList<>(BATCH_SIZE); List<Future> results = new LinkedList<>(); while((line=reader.readLine())!=null){ batch.add(line); if(batch.size()>=BATCH_SIZE){ Future<Object> f = noWaitExec(batch, pool); results.add(f); batch = new ArrayList<>(BATCH_SIZE); } } Future<List> f = noWaitExec(batch,pool); results.add(f); for (Future future : results) { try { Object object = future.get(); // Use your results here } catch (Exception e) { // Manage this.... } } } private static Future<List> noWaitExec(final List<String> batch, ExecutorService pool) { return pool.submit(new Callable<List>() { public List call() throws Exception { List result = new ArrayList<>(batch.size()); for (String string : batch) { result.add(process(string)); } return result; } }); } private static Object process(String string) { // Your process .... return null; };

Hay muchas otras soluciones posibles (Observables, ParallelStreams, Pipes, CompletableFutures ... lo que sea), aún así creo que la mayor parte del tiempo invertido es el tiempo que lleva leer el archivo, solo usando un BufferedInputStream para leer el archivo con un búfer lo suficientemente grande podría reducir sus tiempos más que la computación paralela.

over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda