Frage

Hallo ich habe Klassendefinition wie diese

public class JdbcInterceptor {
private static final JdbcInterceptor instance = new JdbcInterceptor();
private static ThreadLocal<Boolean> dontIntercept = new ThreadLocal<Boolean>();
     public static JdbcInterceptor getInstance() {
 return instance;
}
public void skipIntercept() {
 dontIntercept.set(true);
}
public boolean interrupt() {
boolean di = dontIntercept.get()!=null?dontIntercept.get().booleanValue():false;
if (di) {
        dontIntercept.set(false);
        }
return di;
}// end interrupt
}// end class

Und ich tue dies in einem anderen class1

//class1 stuff
JdbcInterceptor.getInstance().skipIntercept();
if(JdbcInterceptor.getInstance().interrupt())
{ // class1 stuff happens
}

Jetzt dies ich in Klasse 2

//class2 stuff
if(JdbcInterceptor.getInstance().interrupt())
{ // class2 stuff happens
}

Jetzt habe ich in einem wenig Verwirrung bin, weiß ich, dass class1 Sachen passieren werden, weil ich das Set dontIntercept Thread. Mein Zweifel ist, ob class2 Sachen oder nicht passieren? Meine Logik ist, dass ich nur eine Instanz von JdbcInterceptor haben so den gleichen Zustand über alle Anrufe Interrupt () verfügbar sein sollte. Aber ich habe gesagt, dass ThreadLocals für jeden Thread lokal sind. Ich sehe einige Konflikte hier. Bitte helfen Sie mir zu diesem Thema.

War es hilfreich?

Lösung

Ihre Frage ist nicht ganz klar.

  

Aber ich habe gesagt, dass ThreadLocals für jeden Thread lokal sind. Ich sehe einige Konflikte hier.

Das ist richtig. Es gibt keinen Konflikt. Der Wert Objekt mit einem ThreadLocal gespeichert ist einzigartig für jeden Thread. Es ist eigentlich mit dem Thread Objekt intern so, wenn ein Thread beendet alle die lokalen Thread-Werte ebenfalls entfernt und für die Garbage Collection gespeichert sind, es sei denn es gibt noch andere Verweise auf sie von anderen Threads.

Wenn beide Klassen mit dem gleichen Thread ausgeführt werden, dann werden beide haben das gleiche Ergebnis, wenn Sie den Wert des lokalen Thread zwischen den Anrufen wechseln. Wenn ein anderer Thread ausführt CLASS2 dann würde die zwei unterschiedliche Werte haben (pro Ihr Beispiel).

Sie sind verwirrend vielleicht Thread-Ausführung, die in Zeit und Klassen / Methoden der Lagerung und Code auftritt. Diese beiden sind sehr unterschiedlich. Ein Thread kann jede und alle Methoden ausführen oder Sie könnten viele Threads haben die gleiche Methode in einer einzigen Klasse ausgeführt wird. Sie können nicht „sehen“ Threads in Ihrem Code. Ohne ein anderes Bild, das Sie müssen sie sich vorstellen -. Es einige sorgfältige Visualisierung nimmt

Jetzt können Sie Ihren Code ein wenig klarer durch die Verwendung eines ThreadLocal initializer machen, wie folgt aus:

private static ThreadLocal<Boolean> dontIntercept = new ThreadLocal<Boolean>() {

    @Override
    protected Boolean initialValue() {
        return Boolean.FALSE;
    }

};

Wenn Sie dann den lokalen Thread verwenden Sie müssen nicht prüfen, ob es null ist, etwa so:

public boolean interrupt() {
    return dontIntercept.get().booleanValue();
}// end interrupt

Hier ist ein Versuch, zu zeigen, wie diese mit mehr zwei Threads ausführen kann:

 Thread1 start---class1(skip=false)-+-skip(true)---+class1(true)--+class2(true)----+-end
                    |               |              |              |                |
                    Thread2 start---+-class1(false)+--------------+class2(false)---+-class1(false)---end

Wenn ich zeige classN (val), der Wert ist, was der Sprung Thread lokalen Variable zu diesem Zeitpunkt eingestellt ist.

Um genauer beantwortet Ihre Frage dann in diesem Beispiel: class1 und class2 Code werden sowohl übersprungen werden, wenn sie von thread1 ausgeführt. Wenn er ausgeführt wird durch thread2 würden sie nicht übersprungen werden.

Beachten Sie, dass es eine andere Art von Faden ist lokal genannt InheritableThreadLocal. Dies würde sich anders verhalten in meinem Beispiel als Thread2 würde den Wert inhert wie in war Thread1 zu der Zeit, dass Thread den zweiten Thread gestartet.

Bearbeiten Wenn Sie den Code in Class1 den Sprungwert auf true setzt immer dann ändert sich das Verhalten ein wenig. Wenn ein Thread erste führt dann class2 class1 dann werden überspringen true für beide. Wenn ein Thread führt zuerst class2 und dann class1 dann überspringen false für die ersteren und true für die später sein. Sie zeigen nicht, dass es einen Weg gibt, um false zu drehen zu springen.

Bearbeiten Lesen Sie noch einmal Ihre Frage. Wenn Sie in der Tat genau die gleichen Zustand für alle Threads wollen, dann würden Sie nicht einen ThreadLocal verwenden. Verwenden Sie einfach eine reguläre Variable und entweder markieren Sie ihn als volatile oder schützen sie mit der Synchronisation.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top