2010-01-06 17 views
8

Ich bin auf der Suche nach einer Klasse ähnlich ThreadLocal, die auf Thread-Gruppen statt Threads funktionieren würde.Gibt es Thread-Gruppen-lokale Variablen in Java?

Wenn es eine solche Klasse (in einigen Open-Source-Bibliotheken) nicht gibt, wie würden Sie sie implementieren? Eine bessere Idee als Thread-Gruppen in WeakHashMap zu haben?

Ich implementiere ein Debugger-Framework, das in der Laufzeit mit verschiedenen Parametern in globalen, pro Thread- und pro Thread-Gruppenkontexten einstellbar ist. Als einfaches Beispiel können Sie eine Bericht Aussage haben:

debug.log(category, message); 

und angeben, dass der Protokolleintrag mit dieser bestimmten Kategorie wird nur dann, wenn von einem Thread in der Gruppe von Threads Servicenetzwerkanforderungen genannt angezeigt werden.

+1

Aus Gründen der Klarheit möchten Sie vielleicht einige Verwendungsbeispiele werfen. Auch warum/wie du das machen willst. –

+0

@Kevin: Habe nur eine Motivation und ein einfaches Beispiel hinzugefügt. – Viliam

Antwort

4

Ich würde einen Werthalter in einem Thread lokal speichern und ihn für alle Threads der gleichen Gruppe auf denselben Werthalter initialisieren.

public class ThreadGroupLocal<T> extends ThreadLocal<ValueHolder> { 
    private static class ValueHolder { 
     public Object value; 
    } 
    // Weak & Concurrent would be even the better, but Java API wont offer that :(
    private static ConcurrentMap<ThreadGroup, ValueHolder> map = new ConcurrentHashMap<ThreadGroup, ValueHolder>; 
    private static ValueHolder valueHolderForThread(Thread t) { 
     map.putIfAbsent(t.getThreadGroup(), new ValueHolder()); 
     return map.get(t.getThreadGroup()); 
    } 
    @Override 
    protected ValueHolder initialValue() { 
     return valueHolderForThread(Thread.currentThread()); 
    } 
    public T getValue() { (T) get().value; } 
    public void setValue(T value) { get().value = value; } 
} 

und dann

ThreadGroupLocal<String> groupLocal = new ThreadGroupLocal<String>(); 
groupLocal.setValue("foo"); 
//... 
String foo = groupLocal.getValue(); 

verwenden, die nicht (für die Initialisierung erwarten) führen genau wie ein roter Faden lokal.

+0

Warum haben Sie ValueHolder nicht generalisiert? Und warum hast du ThreadLocal erweitert? Die Verwendung von ThreadLocal ist ein Implementierungsdetail. –

+0

Gute Punkte, sie sind es wert, berücksichtigt zu werden. Ich habe diesen Code in aller Eile als Proof-of-Concept geschrieben, also überprüfen Sie ihn (und testen Sie ihn !!!), bevor Sie ihn in der Produktion verwenden. (PS: * Ich erinnere mich jetzt, warum ValueHolder nicht generisch ist, weil sie in einer statischen Hash-Map gespeichert sind, die zu '' degenerieren würde, also müssen Sie trotzdem casten.*) – akuhn

+0

+1, Genau wonach ich gesucht habe. Wissen Sie, ob in der heutigen Java API diese Funktion nativ unterstützt? – dreamcrash

2

Das letzte Mal, als ich mir die Implementierung (vor ein paar Jahren) angeschaut habe, wurden Thread Locals als einfache Hash-Tabelle implementiert, die von der Thread-ID indiziert wurde. Nichts Besonderes und weit weg von der Effizienz von C++.

Sie können das gleiche tun und das Thread-Gruppenobjekt als Schlüssel für Ihre eigene lokale Thread-Gruppen-Hash-Tabelle verwenden.

+0

Even (Sun) 1.2 wurde aktualisiert, um dies nicht zu tun. Es ist sehr ineffizient. –

+0

Ja, ich weiß, es war lange her. – Lothar

+0

Ich denke, es ist jetzt eine Hash-Tabelle innerhalb der Thread-Instanz, indiziert von ThreadLocal-Objekt. Dadurch entfällt der Synchronisationsaufwand, eine private Hash-Tabelle pro Thread. – Thilo

5

ThreadGroup wird selten verwendet, daher gibt es keine Plattformunterstützung.

Die Verwendung von [Weak/Identity/Concurrent] HashMap<ThreadGroup,T> wird gerade funktionieren, wenn nicht sehr schnell. Sie möchten wirklich, dass die Karte alle schwach, identisch und gleichzeitig ist, aber mit der Java-Bibliothek, die Sie derzeit nur zur Auswahl haben.

Um die Leistung zu verbessern, beachten Sie, dass Thread s nicht geändert werden ThreadGroup. Daher cachen Sie den Wert mit einem ThreadLocal (überschreiben initialValue). ThreadLocal hat eine gute Leistung (ein paar Dutzend Zyklen pro get).

+0

Schöne Leistung Trick, danke. – Viliam

+0

+1, für die Leistungsprobleme. Wissen Sie, ob in der heutigen Java API diese Funktion nativ unterstützt? – dreamcrash

Verwandte Themen