2015-10-27 3 views
5

Sto lavorando per migliorare le mie competenze java ma un po 'incerto su come gestire questa applicazione multi-thread. Fondamentalmente, il programma legge un file di testo e trova il numero più grande. Ho aggiunto un ciclo for all'interno del mio algoritmo di ricerca per creare 10 thread ma non sono sicuro che stia effettivamente creando 10 thread. L'idea è di migliorare i tempi di esecuzione, o almeno questo è quello che presumo dovrebbe accadere. È comunque necessario verificare se l'ho fatto correttamente e se il tempo di esecuzione è effettivamente migliorato?Utilizzo di 10 thread per elaborare una matrice

import java.io.BufferedReader; 
import java.io.FileReader; 
import java.io.IOException; 

public class ProcessDataFile { 

    public static void main(String[] args) throws IOException { 

     int max = Integer.MIN_VALUE; 
     int i = 0; 
     int[] numbers = new int[100000]; 
     String datafile = "dataset529.txt"; //string which contains datafile 
     String line; //current line of text file 

     try (BufferedReader br = new BufferedReader(new FileReader(datafile))) { //reads in the datafile 
      while ((line = br.readLine()) != null) { //reads through each line 
       numbers[i++] = Integer.parseInt(line); //pulls out the number of each line and puts it in numbers[] 
      } 
     } 

     for (i = 0; i < 10000; i++){ //loop to go through each number in the file and compare it to find the largest int. 
      for(int j = 0; j < 10; j++) { //creates 10 threads 
       new Thread(); 
      } 
      if (max < numbers[i]) //As max gets bigger it checks the array and keeps increasing it as it finds a larger int. 
       max = numbers[i]; //Sets max equal to the final highest value found. 
     } 


     System.out.println("The largest number in DataSet529 is: " + max); 
    } 
} 
+1

Probabilmente si vorrà iniziare dando un'occhiata al [Concurrency Trail] (https://docs.oracle.com/javase/tutorial/essential/concurrency/). Semplicemente creare un 'nuovo Thread()' in realtà non fa nulla. Una delle cose che potrebbe essere necessario prendere in considerazione è la creazione di un thread che è responsabile della ricerca del valore più grande all'interno di un determinato intervallo dell'array fornito. In questo modo (nel tuo caso) finirai con 10 valori (1 per ogni thread), che poi determineresti quale era il massimo – MadProgrammer

+1

Ah, quindi fai scorrere ciascun thread per 1/10 del set. Quindi confrontare il valore di ogni filo trovato? – Vortex11

+1

Fondamentalmente, è un po 'più complicato come è necessario sapere quando ogni thread è completato, ecc, ma questa è l'idea di base – MadProgrammer

risposta

5

Questo è un esempio molto semplice che dimostra i concetti di base della creazione e l'esecuzione fili che elaborano un determinato intervallo di valori da una matrice specifica. L'esempio fa alcune ipotesi (solo un numero pari di elementi, per esempio). L'esempio è anche un po 'lungo senza fiato e viene fatto in modo volutamente, nel tentativo di dimostrare i passi fondamentali che sarebbero necessari

Iniziare dare un'occhiata a the Concurrency Trail per maggiori dettagli

import java.util.Random; 

public class ThreadExample { 

    public static void main(String[] args) { 
     int[] numbers = new int[100000]; 
     Random rnd = new Random(); 
     for (int index = 0; index < numbers.length; index++) { 
      numbers[index] = rnd.nextInt(); 
     } 

     Thread[] threads = new Thread[10]; 
     Worker[] workers = new Worker[10]; 

     int range = numbers.length/10; 
     for (int index = 0; index < 10; index++) { 
      int startAt = index * range; 
      int endAt = startAt + range; 
      workers[index] = new Worker(startAt, endAt, numbers); 
     } 

     for (int index = 0; index < 10; index++) { 
      threads[index] = new Thread(workers[index]); 
      threads[index].start(); 
     } 

     boolean isProcessing = false; 
     do { 
      isProcessing = false; 
      for (Thread t : threads) { 
       if (t.isAlive()) { 
        isProcessing = true; 
        break; 
       } 
      } 
     } while (isProcessing); 

     for (Worker worker : workers) { 
      System.out.println("Max = " + worker.getMax()); 
     } 

    } 

    public static class Worker implements Runnable { 

     private int startAt; 
     private int endAt; 
     private int numbers[]; 

     private int max = Integer.MIN_VALUE; 

     public Worker(int startAt, int endAt, int[] numbers) { 
      this.startAt = startAt; 
      this.endAt = endAt; 
      this.numbers = numbers; 
     } 

     @Override 
     public void run() { 
      for (int index = startAt; index < endAt; index++) { 
       max = Math.max(numbers[index], max); 
      } 
     } 

     public int getMax() { 
      return max; 
     } 

    } 

} 

una soluzione leggermente più semplice comporterebbe l'API ExecutorService, che consentirebbe di offrire una serie di Callable s al servizio che restituirebbe quindi uno List di Future. Il vantaggio è, il servizio non tornerà fino a che tutti i Callable s hanno completato (o hanno fallito), quindi non è necessario controllare costantemente gli stati dei fili

import java.util.Arrays; 
import java.util.List; 
import java.util.Random; 
import java.util.concurrent.Callable; 
import java.util.concurrent.ExecutionException; 
import java.util.concurrent.ExecutorService; 
import java.util.concurrent.Executors; 
import java.util.concurrent.Future; 

public class ThreadExample { 

    public static void main(String[] args) { 
     int[] numbers = new int[100000]; 
     Random rnd = new Random(); 
     for (int index = 0; index < numbers.length; index++) { 
      numbers[index] = rnd.nextInt(); 
     } 

     ExecutorService executor = Executors.newFixedThreadPool(10); 

     Worker[] workers = new Worker[10]; 

     int range = numbers.length/10; 
     for (int index = 0; index < 10; index++) { 
      int startAt = index * range; 
      int endAt = startAt + range; 
      workers[index] = new Worker(startAt, endAt, numbers); 
     } 

     try { 
      List<Future<Integer>> results = executor.invokeAll(Arrays.asList(workers)); 
      for (Future<Integer> future : results) { 
       System.out.println(future.get()); 
      } 
     } catch (InterruptedException | ExecutionException ex) { 
      ex.printStackTrace(); 
     } 

    } 

    public static class Worker implements Callable<Integer> { 

     private int startAt; 
     private int endAt; 
     private int numbers[]; 


     public Worker(int startAt, int endAt, int[] numbers) { 
      this.startAt = startAt; 
      this.endAt = endAt; 
      this.numbers = numbers; 
     } 

     @Override 
     public Integer call() throws Exception { 
      int max = Integer.MIN_VALUE; 
      for (int index = startAt; index < endAt; index++) { 
       max = Math.max(numbers[index], max); 
      } 
      return max; 
     } 

    } 

} 
+0

Grazie mille per questi esempi. Vedrò cosa posso fare e costruirmi. Molto apprezzato! – Vortex11