2016-06-01 9 views
0

Ich benutze ConcurrentSkipListSet-Sammlung, um mit gleichzeitigen Operator umzugehen. Ich finde es manchmal stecken, reproduct mit diesem Code:Thread fest, wenn Java verwenden ConcurrentSkipListSet Methode hinzufügen

import java.util.Comparator 
import java.util.concurrent._ 

object SetDeadLock extends App { 
    private val tasks = new ConcurrentSkipListSet[Task](new Comparator[Task](){ 
    override def compare(o1: Task, o2: Task): Int = { 
     val compare = (o1.systemTime - o2.systemTime).toInt 
     if (compare == 0) 1 else compare //distinct same time task 
    } 
    }) 

    for(i <- 1 to 20) { 
    tasks.add(Task()) 
    println(s"added - $i") 
    } 

    case class Task() { 
    val systemTime = System.currentTimeMillis() 
    } 
} 

Ausgabe

added - 1 
added - 2 

Es vielleicht an anderen stecken, dabei vor allem der Komparator benutzerdefinierte Sortier Daten Methode sind sie gleich (weil Set nicht unterstützen dasselbe Element) und alle Task ist neue Instanz, sollte es keinen Konflikt mit anderen sein.

mit jstack cmd, der Haupt-Thread stecken

at java.util.concurrent.ConcurrentSkipListMap.findPredecessor(ConcurrentSkipListMap.java:685) 

tut es ein Fehler war oder ich nur ein Prinzip irreführend?

Danke jede Hilfe oder Beratung.

UPDATE
Ich versuche gerade jetzt if (compare == 0) 1 else compare zu if (compare == 0) -1 else compare ändern, überraschend, arbeite ich gut!

Kann jemand klären, wie es funktioniert? Source-Code ist es schwierig für mich (und ich denke, dass viele Leute mir zustimmen), schließlich, jdk viele Arbeiten für die Maschine ausführen Geschwindigkeit nicht für Codeleser.

Schließlich
Um die peinliche Situation zu vermeiden, nur etwas anders Faktor comparator machen, welche Set ‚s Semantik übereinstimmen, wie eine zufällige value.but anhängt seine Ich denke, besser eine andere echte geeignete Sammlung zu finden sein.

Vor ein paar Tagen finde ich eine gute Idee, HashCode als zweite Überprüfung verwenden, wenn SystemTime gleich ist. hoffe hilfreich ~

+0

wahrscheinlich so schnell, dass Sie mit identischen Zeiten enden, während der Komparator sagt gleiche Zeit = anders. Ich bin mir nicht sicher, wie es implementiert wird, aber ich könnte mir vorstellen, dass das eine hässliche Schleife verursacht, weil a zapl

+0

@zapl, meinst du, es war ein Fehler, der durch 'Comparator' verursacht wurde? Schlaf 500 Millis hat auch das Problem – LoranceChen

Antwort

1

Ihr Komparator ist nicht stabil. Ich glaube nicht, ConcurrentSkipListMap verspricht, sich gut zu verhalten, wenn verschiedene Aufrufe inkonsistente Ergebnisse geben. Zum Beispiel, je nachdem, wie Sie anrufen, können Sie sowohl eine < b und b < a gleichzeitig mit Ihrem Code denken.

+0

Ich habe etwas über die Mittel von nicht stabil zu verwechseln, mit anderen Worten, sollte ich <, > definieren, und =? Ich will Shop hat gleiche SystemTime-Element, wie wir wissen, "add" -Methode wird eine falsche wenn Komparator Ergebnis als 0 zurückgegeben. – LoranceChen

+0

@LananceChen - Etwas ist "stabil", wenn es das gleiche Ergebnis jedes Mal, wenn Sie fragen, unabhängig davon, wie Sie Fragen. Wenn in Ihrem Fall "a" und "b" denselben "systemTime" -Wert haben, dann ist "ein Vergleich b" 1 und bedeutet "a> b". Aber "b vergleichen a" ist auch "1", was bedeutet "b> a" bedeutet "a

+0

Ich denke, ich habe den Grund warum instabil.Meine aktuelle Lösung vielleicht auch bei anderen Java-Version stecken.Ich brauche einen echten vergleichbaren Faktor für 'Set'.Vielen Dank. – LoranceChen