A classe Threadlocal representa uma variável local de thread. Ao colocar os dados no ThreadLocal, cada thread pode criar uma cópia da variável. Também pode ser considerado como outra maneira de sincronização de threads. Ao criar uma cópia local de uma variável para cada thread, ela evita conflitos quando threads simultâneos leem e escrevem o mesmo recurso variável ao mesmo tempo.
Exemplos são os seguintes:
importar java.util.random; importar java.util.concurrent.executorService; importar java.util.concurrent.executores; importar java.util.concurrent.timeunit; import com.sun.javafx.webkit.accessor; public class; Threadlocal <Teger> value = new Threadlocal <Teger> () {private aleatório aleatório = novo aleatório (); Incronizado Incronizado protegido InitialValue () {return aleatom.nextInt (10000); }}; public static void increment () {value.set (value.get () + 1); } public static int get () {return value.get (); }} classe estática Acessor implementa Runnable {private final int id; Acessor público (int id) {this.id = id; } @Override public void run () {while (! Thread.currentThread (). IsInterrupted ()) {threadLocalVariableholder.increment (); System.out.println (this); Thread.yield (); }} @Override public string tostring () {return "#" + id + ":" + threadlocalvariableholder.get (); }} public static void main (string [] args) {executorService executorService = executores.newcachedthreadpool (); for (int i = 0; i <5; i ++) {ExecUserService.execute (novo acessador (i)); } tente {timeUnit.microseconds.sleep (1); } catch (interruptedException e) {e.printStackTrace (); } executorService.shutdownNow (); }}Resultados em execução:
#1: 9685#1: 9686#2: 138#2: 139#2: 140#2: 141#0: 5255.. .
A partir dos resultados em execução, podemos ver que cada thread é usado para suas próprias variáveis locais, e cada leitura e gravação não interfere entre si.
O ThreadLocal fornece três métodos para operar, definir, obter e remover.
No Android, o Threadlocal é usado para criar objetos looper separados para cada thread.
classe final pública Looper {private estático final string tag = "looper"; // sthreadlocal.get () retornará nulo, a menos que você tenha chamado preparar (). estático final ThreadLocal <Ooper> sthReadLocal = new Threadlocal <Ooper> (); Void estático privado Prepare (boolean parou) {if (sthreadlocal.get ()! = null) {lança nova runtimeException ("apenas um looper pode ser criado por thread"); } sthreadlocal.set (new Looper (calada)); }. . . }Quando um thread precisa de sua própria fila de looper e mensagem, ele chama looper.Prepare (), que criará um objeto Looper e MessageQueue pertencente ao thread para o thread e salve o objeto Looper no Threadlocal.