2010-05-10 64 views
1

這個程序在Java中產生15個號碼的列表,並創建3個線程在給定的時間間隔,以搜索最大臨危值的線程。我想創建另一個線程,這3個數字並獲得最大值。但我不知道如何在其他線程中獲取這些值。使從其他線程

public class apple implements Runnable{ 

String name; 
int time, number, first, last, maximum; 
int[] array = {12, 32, 54 ,64, 656, 756, 765 ,43, 34, 54,5 ,45 ,6 , 5, 65}; 


public apple(String s, int f, int l){ 
    name = s; 
    first = f; 
    last = l; 
    maximum = array[0]; 
} 



public void run(){ 
    try{ 

     for(int i = first; i < last; i++) 
     { 

      if(maximum < array[i]) 
      { 
       maximum = array[i]; 
      } 
     } 

     System.out.println("Thread"+ name + "maximum = " + maximum); 

    }catch(Exception e){} 
    } 



public static void main(String[] args){ 
    Thread t1 = new Thread(new apple("1 ", 0, 5)); 
    Thread t2 = new Thread(new apple("2 ", 5, 10)); 
    Thread t3 = new Thread(new apple("3 ", 10, 15)); 

    try{ 

     t1.start(); 
     t2.start(); 
     t3.start(); 
     }catch(Exception e){} 

} 

}

回答

0

而是實現Runnable,儘量實現可調用,這是能夠返回一個結果。給出here本教程是用於描述如何做到這一點的良好來源。

你的問題的另一種方法可能是創建一個對象,其中每個apple實例(不知道你爲什麼稱它爲止)可以在對象中註冊其最大值。這個新的類可以被傳遞到每個apple構造函數,那麼apple可以調用一個方法,傳遞了自己的最大到此。

例如:

public class MaximumOfMaximumsFinder implements Runnable { 
    private List<Integer> maximums = new ArrayList<Integer>(); 

    public void registerSingleMaximum(Integer max) { 
     maximums.add(max); 
    } 

    public void run() { 
     // use similar logic to find the maximum 
    } 
} 

周圍有確保這種協調與其他線程的幾個問題,我將離開這個給你,因爲有一些有趣的事情要考慮。

2

這裏是ExecutorService的和ExecutorCompletionService如何解決:

public class MaxFinder { 
    private int[] values; 
    private int threadsCount; 

    public MaxFinder(int[] values, int threadsCount) { 
     this.values = values; 
     this.threadsCount = threadsCount; 
    } 

    public int find() throws InterruptedException { 
     ExecutorService executor = Executors.newFixedThreadPool(threadsCount); 
     ExecutorCompletionService<Integer> cs = new ExecutorCompletionService<Integer>(executor); 

     // Split the work 
     int perThread = values.length/threadsCount;  
     int from = 0; 
     for(int i = 0; i < threadsCount - 1; i++) { 
      cs.submit(new Worker(from, from + perThread)); 
      from += perThread; 
     } 
     cs.submit(new Worker(from,values.length)); 

     // Start collecting results as they arrive 
     int globalMax = values[0]; 
     try {   
      for(int i = 0; i < threadsCount; i++){ 
       int v = cs.take().get(); 
       if (v > globalMax) 
        globalMax = v; 
      } 
     } catch (ExecutionException e) { 
      throw new RuntimeException(e); 
     } 

     executor.shutdown(); 
     return globalMax; 
    } 

    private class Worker implements Callable<Integer> { 
     private int fromIndex; 
     private int toIndex; 

     public Worker(int fromIndex, int toIndex) { 
      this.fromIndex = fromIndex; 
      this.toIndex = toIndex; 
     } 

     @Override 
     public Integer call() { 
      int max = values[0]; 
      for(int i = fromIndex; i<toIndex; i++){ 
       if (values[i] > max) 
        max = values[i]; 
      } 
      return max; 
     }  
    } 
} 

在此解決方案,N線程同時工作,每個在陣列的其一部分。調用者線程負責收集到達時的局部最大值,並查找全局最大值。該解決方案使用java.util.concurrent包中的一些非平凡的併發工具。

如果您希望只使用原始的同步工具的解決方案,那麼你應該使用的工作線程同步的塊中,設定最大的一些數據成員,然後通知收集器線程。收集器線程應該處於循環狀態,等待通知,然後檢查新數字,並根據需要更新全局最大值。這種「消費者生產者」模式需要謹慎的同步。

+0

+1很好的回答:) – Grundlefleck 2010-05-11 09:07:47

1

根據你的代碼,最簡單的辦法就是主線程加入到每個實例線程,然後從他們那裏得到的最大值進行比較。像這樣:

int globalMax; 

try{ 

    t1.start(); 
    t2.start(); 
    t3.start(); 

    t1.join(); 
    globalMax = t1.maximum; 

    t2.join(); 
    if (t2.maximum > globalMax) { 
     globalMax = t2.maximum; 
    } 

    t3.join(); 
    if (t3.maximum > globalMax) { 
     globalMax = t3.maximum; 
    } 
} catch(Exception e){ 
}