2017-12-07 19 views
0

Ich bin durch eine Karte, und ich habe eine Reihe von Threads. Die Warteschlange in der Karte enthält Aktionen. Mein Ziel ist es, jedem Thread eine Aktion zu geben. Aber keine 2 Threads (oder mehr) können 2 Aufgaben (oder mehr) aus einer Warteschlange ausführen. bedeutet, dass jeder Thread nach einer Warteschlange sucht und die Warteschlange wie blockiert und prüfen, ob die Warteschlange Aktionen hat, wenn ja, führt sie eine von ihnen aus, wenn keine Suche nach einer anderen Warteschlange für diese Aktionen ausgeführt wird. HINWEIS: Anzahl der Warteschlangen kann größer sein als Anzahl der Threads e ich auf dem ‚Map.Entry‘ zu synchronisieren versuchteSynchronisation und Semaphor

 public void run() { 

      while (true) { 
       Action<?> act; 
       for (Map.Entry entry :ActionMap.entrySet()) { 
        Synchronized(entry) 
        { 
         act = ((Queue<Action>)entry.getValue()).poll(); 
         if (act == null) 
         break; 
        } 
       } 

      } 
      } 

das Problem, dass, wenn ein anderer Thread für eine Aktion sucht würde zu tun ist, in der synchronisierten Linie hängen bleiben und auf den ersten Thread warten, um die Aufgabe zu beenden oder zu beenden und das ist nicht das, was ich will. ich will alle Threads für Warteschlangen suchen, wenn einige ein Thread eine Warteschlange erreicht, dass ein anderer Thread auf überspringen funktioniert es gerade und weitersuchen

so digged ich mich um und fand Semaphore so erreichte ich diesen

Semaphore Gate = new Semaphore(1); 



     public void run() { 

      while (true) { 
       Action<?> act; 
       for (Map.Entry entry :ActionMap.entrySet()) { 
        if(Gate.tryAcquire()); 
        { 
         act = ((Queue<Action>)entry.getValue()).poll(); 
         if (act == null){ 
        Gate.Release(); 
        break; 

         } 
         else { 
         act.handle(); 
         Gate.Release(); 
        } 
        } 
       } 

      } 
      } 

stellen das Problem mit dieser dass Gate.aquire() alle Einträge werde Lock ist es bedeutet, für 2 diffirent Einträge und 2 verschiedene Threads nur ein Thread das Gate zugreifen kann, und führen die Aktion

so schließlich jede eine Dosis haben ein Designmuster, das mir helfen kann? danke ...

+0

Das klingt wie ein [XY-Problem] (https://meta.stackexchange.com/a/66378). Was wäre, wenn Sie nur _one_ thread hätten, der die Map scannt und Aufgaben an einen [thread pool] sendet (https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ThreadPoolExecutor.html)? ? –

+0

Ich fühle, dass ich in der Erklärung nicht klar war, ich gab zwei Gedanken und sagte, dass sie mir nicht geben, was ich will ... ich tat das, um mein Problem zu klären. Ich warte nicht auf jemanden, der mir sagt, wie ändere meinen Code. anders als dass Ihre Lösung wird nicht helfen, ich habe Einträge jeden Eintrag enthält Warteschlange in dieser Warteschlange gibt es eine Aktionen der Thread Job Einträge (Queues) finden und Aktionen ausführen muss .. mit einigen Einschränkungen zu wissen über sie können Sie oben lesen .. –

+0

Ich habe eine Lösung dafür gefunden, nachdem alle ... ihre Semaphore zu modifizieren ... eine Kombination zwischen Semaphor und "syncronized" ......... danke irgendeinen Weg –

Antwort

1

Sie könnten java.util.concurrent Arten von Karte dafür verwenden. Sie sind threadsicher, also brauchen Sie Syncronize nicht.

Synchronisieren bedeutet: Die Ressource (die synchronisiert ist) kann nicht gleichzeitig von mehreren Threads geändert werden. Beispiel: MAP, das von Collections.synchronizedMap (Map) zurückgegeben wird, ist eine synchronisierte Map und kann jeweils um einen Thread geändert werden, aber Concurrent Collections ermöglicht mehreren Threads den Zugriff auf verschiedene Teile einer Sammlung zu einem bestimmten Zeitpunkt basierend auf der Anforderung. Zum Beispiel haben wir einen überladenen Konstruktor für ConcurentHashMap, der die Eingabe concurrencyLevel als Anzahl von Threads verwendet, die gleichzeitig auf die Sammlung zugreifen können.

+0

Ich kann irgendwie die Concurrent Collections neben dem verwenden, wenn 2 Threads versuchen, die Sammlung zu ändern, einer von ihnen muss warten ... aber in meinem Fall, wenn 2 Threads versucht, zwei verschiedene Einträge zu ändern, sollten sie nicht warten –

+0

Das ist genau Wats Concurrent Collectoins sind für, Threads messing die gleiche Karte = P –

+0

Wenn zwei Threads versuchen, zwei verschiedene Einträge zu bekommen, muss einer von ihnen richtig warten? –