2010-05-10 2 views
1

Ce programme en Java crée une liste de 15 nombres et crée 3 threads pour rechercher le maximum dans un intervalle donné. Je veux créer un autre thread qui prend ces 3 chiffres et obtenir le maximum. mais je ne sais pas comment obtenir ces valeurs dans l'autre thread.créer un fil qui reçoit des valeurs d'autres threads

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){} 

} 

}

Répondre

0

Au lieu de mettre en œuvre Runnable, essayez la mise en œuvre appelable, qui est capable de retourner un résultat. Le tutoriel donné here est une bonne source pour décrire comment faire cela.

Une autre approche de votre problème pourrait être de créer un objet dont chaque instance apple (je ne sais pas exactement pourquoi vous l'avez appelé ceci) pourrait enregistrer son maximum avec l'objet. Cette nouvelle classe peut être passée dans chaque constructeur apple, puis le apple peut appeler une méthode, en lui passant son propre maximum.

Par exemple:

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

Il y a plusieurs questions autour de s'être assuré que c'est coordonné avec les autres fils de discussion, je vais laisser cela pour vous, car il y a des choses intéressantes à penser.

2

Voici comment ExecutorService et ExecutorCompletionService peuvent résoudre:

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

Dans cette solution, N fils travaillent en même temps chacun sur sa partie du tableau. Le thread appelant est chargé de rassembler les maximums locaux dès leur arrivée et de trouver le maximum global. Cette solution utilise des outils de simultanéité non triviaux du package java.util.concurrent. Si vous préférez une solution qui utilise uniquement des outils de synchronisation primitive, vous devez utiliser un bloc synchronisé dans les threads de travail, qui définit le maximum dans certains membres de données, puis notifie le thread de collecteur. Le thread collecteur doit être dans une boucle, en attente d'une notification, puis en examinant le nouveau numéro et en mettant à jour le maximum global si nécessaire. Ce modèle de "producteur de consommation" nécessite une synchronisation soigneuse.

+0

+1 Bonne réponse :) – Grundlefleck

1

Selon le code dont vous disposez, la solution la plus simple consiste à joindre le thread principal à chaque thread d'instance, puis d'en extraire la valeur maximale à des fins de comparaison. Comme si:

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){ 
} 
Questions connexes