2015-12-30 6 views
8

In Java 8, bekam java.lang.Thread Klasse 3 neue Felder:Neue zusätzliche Felder in java.lang.Thread, was ist die Idee?

/** The current seed for a ThreadLocalRandom */ 
@sun.misc.Contended("tlr") 
long threadLocalRandomSeed; 

/** Probe hash value; nonzero if threadLocalRandomSeed initialized */ 
@sun.misc.Contended("tlr") 
int threadLocalRandomProbe; 

/** Secondary seed isolated from public ThreadLocalRandom sequence */ 
@sun.misc.Contended("tlr") 
int threadLocalRandomSecondarySeed; 

als es ausschließlich verwaltet in Javadoc sagte java.util.concurrent.ThreadLocalRandom nach Klasse für zu werden.

Weiterhin in ThreadLocalRandom sie in sehr freakish Weise verwendet:

SEED = UNSAFE.objectFieldOffset 
    (tk.getDeclaredField("threadLocalRandomSeed")); 
PROBE = UNSAFE.objectFieldOffset 
    (tk.getDeclaredField("threadLocalRandomProbe")); 
SECONDARY = UNSAFE.objectFieldOffset 
    (tk.getDeclaredField("threadLocalRandomSecondarySeed")); 

(das gleiche Code Stück kann auch in LockSupport Klasse erfüllt werden).

und dann diese Offsets intern in mehreren java.concurrent Orten verwendet werden.

Was ist die Idee? Warum sind diese Felder innerhalb von java.lang.Thread? Warum nicht innerhalb ThreadLocalRandom?

+2

Keine Ahnung von diesem - ich hätte/hätte eigentlich eine Antwort auf deine vorherige Frage bezüglich des '' tlr'' gehabt. – luk2302

+0

@ luk2302 Tolle Antwort, ich danke dir vielmals, aber jemand hat meine Frage runtergestimmt, also muss ich sie löschen. Es tut mir wirklich leid. – Andremoniy

+2

Downvotes sind kein Grund, Fragen oder Antworten zu löschen. Ich habe Ihnen zum Beispiel eine Upvote gegeben, die eine Punktzahl von 0 ergibt. – luk2302

Antwort

6

Dies sind interne Felder. Erklärungen können nur von JDK-Entwicklern selbst kommen. Ich konnte eine post darüber von Doug Lea Januar 2013 finden, die die Gründe hinter diesen Feldern erklärt und warum sie innerhalb der Thread Klasse sind.

Wenn wir ThreadLocalRandom eingeführt, wir konservativ implementiert es eine tatsächliche ThreadLocal zu verwenden. Jedoch, , wie es weiter verbreitet wird, ist es wert, die Implementierung von Gehäuse ThreadLocalRandom Zustand (und zugehörige Buchhaltung) in Klasse Thread selbst zu verbessern. Dies würde drei Felder umfassen (16 Byte insgesamt).

Ich schlage vor, das Hinzufügen der folgenden Klasse Thread So:

// The following three initially uninitialized fields are exclusively 
// managed by class java.util.concurrent.ThreadLocalRandom. 
/** The current seed for a ThreadLocalRandom */ 
long threadLocalRandomSeed; 
/** Probe hash value; nonzero if threadLocalRandomSeed initialized */ 
int threadLocalRandomProbe; 
/** Secondary seed isolated from public ThreadLocalRandom sequence */ 
int threadLocalRandomSecondarySeed; 

die Gründe dafür in dieser Art und Weise zu tun, sind:

  1. Einheitlich schnelleren Zugriff auf ThreadLocalRandom Zustand. Während ThreadLocal Zugang normalerweise ziemlich schnell schon ist, dann ist dies nicht nur schneller, es nicht in den Fällen nicht abbaut, wo Benutzer Programme eines große Anzahl von ThreadLocal s schaffen, der kann (probabilistisch) verursacht beliebigen Zugang langsamer zu werden.

  2. Geringere Gesamtfläche für jedes Programm mit ThreadLocalRandom. Drei Felder benötigen weniger Platz als ein gepolstertes ThreadLocal Objekt. Als ThreadLocalRandom wird weit verbreitet innerhalb JDK selbst, dies umfasst fast alle Programme.

  3. Weitere Zeit-/Raumersparnis für java.util.concurrent ForkJoinPool, ConcurrentHashMap, LongAdder, ConcurrentSkipList und andere Klassen, die diese Form der einheitlichen ThreadLocalRandom Buchhaltung nutzen könnten, anstatt ihre eigenen Spezial-ThreadLocal s wie sie es jetzt tun.

+0

Vielen Dank für Papier Link, +1. Aber diese Lösung sieht etwas chaotisch aus, oder? – Andremoniy

+0

Außerdem verstehe ich nicht wirklich, warum diese Felder nicht innerhalb der 'ThreadLocalRandom' Klasse platziert werden können. – Andremoniy

+2

@Andremoniy Ich bin ehrlich gesagt nicht in der Lage, technische Lösungen der JDK-Entwickler selbst zu beurteilen. Der Grund, warum sie zu Thread hinzugefügt wurden, kommt wahrscheinlich auf diesen Kommentar von Doug Lea zurück: "Aber meistens: Der Platz für" permanente "Thread-Locals muss irgendwo platziert werden, warum nicht den Platz wählen, der die wenigsten Logistikprobleme aufweist? Beachten Sie, dass die Klasse java.lang.Thread nur die sichtbare Spitze des Eisbergs des per-thread-Speichers auf Systemen ist. also ist das Hinzufügen von 16 Bytes alles andere als nicht nachweisbar. " – Tunaki

1

Ich werde dies wieder aufleben lassen, indem auch eine kleine Antwort geben, da ich gerade dies in LongAdder getroffen habe und es gibt eine große Video, wo Shipilev dies in einfachen Worten erklärt (in russisch ist), ist hier die Verbindung: ThreadLocalRandom

Für den Fall von ForkJoinPool muss es Aufgaben in eine Warteschlange stellen und aus einer Warteschlange entfernen, welche Warteschlange exaclty über eine gute PRNG gelöst wird.

Dieses prng muss sehr schnell und hochskalierbar sein. Nun, Java hat einen Platz: ThreadLocalRandom. Damit diese Felder in ThreadLocalRandom eingefügt werden können, benötigt es ein ThreadLocal, das wiederum intern eine ThreadLocalMap verwendet (think HashMap).

ThreadLocal.get (denke, HashMap # get) ist viel langsamer als diese Felder direkt von Thread erhalten.

Verwandte Themen