java em uso ThreadLocal
ThreadLocal usado principalmente para armazenar dados para o segmento atual, o segmento atual só pode acessar os dados.
Na definição de ThreadLocal, podemos definir um tipo específico de objecto armazenado na ThreadLocal simultaneamente.
ThreadLocal<Integer> threadLocalValue = new ThreadLocal<>();
复制代码
Acima, definimos um armazenamento ThreadLocal objetos de Integer.
ThreadLocal para armazenar e recuperar objetos também é muito simples de usar get () e set () para:
threadLocalValue.set(1);
Integer result = threadLocalValue.get();
复制代码
Posso ThreadLocal visto como um mapa, e o segmento atual é mapear a chave.
Além de um novo objeto ThreadLocal, também pode:
public static <S> ThreadLocal<S> withInitial(Supplier<? extends S> supplier) {
return new SuppliedThreadLocal<>(supplier);
}
复制代码
métodos estáticos ThreadLocal fornecido withInitial para inicializar um ThreadLocal.
ThreadLocal<Integer> threadLocal = ThreadLocal.withInitial(() -> 1);
复制代码
Fornecedor withInitial requer um alvo, o valor inicial adquirida pela chamando o método do fornecedor get ().
Para apagar os dados armazenados no ThreadLocal, você pode ligar no:
threadLocal.remove();
复制代码
Agora eu comparando dois exemplos, olhar para os benefícios de usar o ThreadLocal.
Em aplicações práticas, muitas vezes precisamos solicitar uma armazenar informações de usuário diferente para diferentes usuários, em geral, precisamos construir um mundial do Mapa para a armazenar informações de usuário diferente, dependendo da ID de usuário, para facilitar o acesso à parte traseira .
Armazenar dados do usuário em um mapa
Se olharmos para como usar o uso global do Mapa:
public class SharedMapWithUserContext implements Runnable {
public static Map<Integer, Context> userContextPerUserId
= new ConcurrentHashMap<>();
private Integer userId;
private UserRepository userRepository = new UserRepository();
public SharedMapWithUserContext(int i) {
this.userId=i;
}
@Override
public void run() {
String userName = userRepository.getUserNameForUserId(userId);
userContextPerUserId.put(userId, new Context(userName));
}
}
复制代码
Aqui definimos um mapa estático de informações do usuário de acesso.
Olhe novamente para como usar:
@Test
public void testWithMap(){
SharedMapWithUserContext firstUser = new SharedMapWithUserContext(1);
SharedMapWithUserContext secondUser = new SharedMapWithUserContext(2);
new Thread(firstUser).start();
new Thread(secondUser).start();
assertEquals(SharedMapWithUserContext.userContextPerUserId.size(), 2);
}
复制代码
Armazenar dados do usuário em um ThreadLocal
Se nós queremos usar em um ThreadLocal você pode fazer:
public class ThreadLocalWithUserContext implements Runnable {
private static ThreadLocal<Context> userContext
= new ThreadLocal<>();
private Integer userId;
private UserRepository userRepository = new UserRepository();
public ThreadLocalWithUserContext(int i) {
this.userId=i;
}
@Override
public void run() {
String userName = userRepository.getUserNameForUserId(userId);
userContext.set(new Context(userName));
System.out.println("thread context for given userId: "
+ userId + " is: " + userContext.get());
}
}
复制代码
código de teste é o seguinte:
public class ThreadLocalWithUserContextTest {
@Test
public void testWithThreadLocal(){
ThreadLocalWithUserContext firstUser
= new ThreadLocalWithUserContext(1);
ThreadLocalWithUserContext secondUser
= new ThreadLocalWithUserContext(2);
new Thread(firstUser).start();
new Thread(secondUser).start();
}
}
复制代码
Após a corrida, temos os seguintes resultados:
thread context for given userId: 1 is: com.flydean.Context@411734d4
thread context for given userId: 2 is: com.flydean.Context@1e9b6cc
复制代码
informações de usuário diferente é armazenado em um ambiente de thread diferente.
Note que usamos ThreadLocal, ele deve ser thread podemos controlar a liberdade de criação. Se no ambiente ExecutorService, é melhor não usar ThreadLocal, porque em ExecutorService, o segmento não é controlável.
Exemplos aqui descritos podem referenciar github.com/ddean2009/l ...
Por favor, consulte mais tutoriais de blog dos flydean