Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

300
Views
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 answers
Answer question

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 Report

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 Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!