2017-09-02 1 views
0

entrez le code hereSuppose J'ai deux threads Thread1 et Thread2 et ci-dessous hashmap avec des valeurs nulles. Maintenant, je veux imprimer la clé de HashMap avec du fil respectif qui est en cours d'exécution déclaration d'impression, sans l'imprimer à nouveauImpression des clés de HashMap avec deux threads en java?

Entrée hashmap:

« Bonjour » null

« client » null

"Value" null

"Bye" null

Sortie:

"Bye": Imprimé par Thread1"

"Bonjour": "Imprimé par Thread2"

"Valeur": "Imprimé par Thread2"

"Client": "Imprimé par Thread1"

Jusqu'à présent, je ne suis pas en mesure d'imprimer avec le code ci-dessous.

import java.util.ArrayList; 
import java.util.Collection; 
import java.util.Collections; 
import java.util.HashMap; 
import java.util.List; 
import java.util.Map; 

public class Test2 implements Runnable { 
    volatile static HashMap<String, String> map; 

    static Object mutex = new Object(); 

    static volatile int i = 1; 

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

     map = new HashMap(); 

     map.put("Public", null); 
     map.put("Sort", null); 
     map.put("Message", null); 
     map.put("Customer", null); 
     map.put("Bank", null); 
     // ConcurrentHashMap chm= new ConcurrentHashMap(map); 

     Collections.synchronizedMap(map); 

     Thread t1 = new Thread(new Test2()); 
     Thread t2 = new Thread(new Test2()); 
     t1.start(); 
     t2.start(); 

    } 

    @Override 
    public void run() { 
     synchronized (mutex) { 

      for (Map.Entry entry : map.entrySet()) { 

       if (entry.getValue() == null) { 
        System.out.println(entry.getKey() + "\" : \"Printed by " + Thread.currentThread().getName() + '\"'); 

        map.put((String) entry.getKey(), Thread.currentThread().getName()); 

        if (Thread.currentThread().getName().contains("0")&&i==1) { 
         try { 
          mutex.notifyAll(); 

          mutex.wait(); 
         } catch (InterruptedException e) { 
          // TODO Auto-generated catch block 
          e.printStackTrace(); 
         } 
        } 
        if (Thread.currentThread().getName().contains("1")&&i<=1) { 
         try { 
          mutex.notifyAll(); 
          i++; 
          mutex.wait(); 
         } catch (InterruptedException e) { 
          // TODO Auto-generated catch block 
          e.printStackTrace(); 
         } 
        } 

       } 
      } 
      mutex.notifyAll(); 

     } 
    } 
} 
+1

Et le problème est? – Kamil

+0

Impossible de trouver un moyen d'imprimer les clés une seule fois. @Kamil –

+0

Collecter les clés d'une liste, la diviser en deux, passer la première moitié au premier thread, et la seconde moitié le deuxième thread, démarrer les deux threads? Je ne sais pas pourquoi vous feriez cela, mais vous le pouvez. Si vous voulez pratiquer avec le multithreading, vous devriez trouver un cas d'utilisation plus réaliste et plus utile. –

Répondre

2

Il suffit de passer chaque clé comme une tâche à un ExecutorService avec 2 fils:

ExecutorService executorService = Executors.newFixedThreadPool(2); 

map.keySet().forEach(key -> executorService 
    .execute(() -> System.out.println('\"' + key + "\" : \"Printed by " + Thread.currentThread().getName() + '\"'))); 

executorService.shutdown(); 
executorService.awaitTermination(5, TimeUnit.SECONDS); 
+0

un moyen de se débarrasser du nom de la piscine dans Threadname? –

+1

@RaviGodara Sure: utilisez la méthode 'newFixedThreadPool' qui prend un ThreadFactory comme deuxième argument, et passez une méthode qui nomme les threads comme vous le souhaitez. – bowmore

+0

Cela fonctionne, Une autre question, pourquoi le service Executor se comporte threadsafe? Contrairement à la création de deux threads séparément. –