2015-10-27 26 views
5

我正在努力提高自己的Java技能,但有點不確定如何處理這個多線程應用程序。基本上,程序讀取一個文本文件並找到最大的數字。我在我的搜索算法中添加了一個for循環來創建10個線程,但我不確定它是否實際創建了10個線程。這個想法是提高執行時間,或者至少這是我認爲應該發生的事情。無論如何要檢查我是否做得正確,執行時間是否確實有所改善?使用10個線程處理數組

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

您可能會想開始通過查看[併發路徑](https://docs.oracle.com/javase/tutorial/essential/concurrency/)。簡單地創建一個'new Thread()'實際上並沒有做任何事情。您可能需要考慮的一件事是創建一個線程,該線程負責在提供的數組的給定範圍內查找最大值。這樣你會(在你的情況下)最終得到10個值(每個線程1個),然後你會確定哪個是最大的 – MadProgrammer

+1

啊好的,所以每個線程搜索整個集合的1/10。然後比較每個線程找到的值? – Vortex11

+1

基本上,因爲你需要知道每個線程何時完成等等,所以它有點複雜,但這是基本思想 – MadProgrammer

回答

5

這是一個非常基本的例子,它演示了創建和運行線程的基本概念,該線程處理來自特定數組的值的給定範圍。這個例子做了一些假設(例如只有偶數個元素)。這個例子也略有長篇大論,並且這樣做故意,試圖證明其通過採取看看the Concurrency Trail更多細節

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

    } 

} 

稍微簡單的解決方案需要

開始的基本步驟將涉及ExecutorService API,這將允許您向該服務提供一系列Callable,然後返回FutureList。這裏的好處是,該服務將不會返回,直到所有的Callable■找完成(或失敗),這樣你就不需要經常檢查線程的狀態

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

非常感謝您爲這些示例。我會看看我能做些什麼,並從中解脫出來。非常感激! – Vortex11