Aprofunde-se no Java ThreadLocal
Fonte: Devgenios Hoje você aprenderá sobre ThreadLocal, uma das classes comuns usadas no desenvolvimento de aplicativos Java.O que é ThreadLocal?
A classe ThreadLocal armazena variáveis locais para threads. Essas variáveis são isoladas entre threads diferentes e só podem ser acessadas por seu próprio thread. Casos de uso para ThreadLocal :- Isole dados entre threads.
- Gerenciamento de sessão para conexões de banco de dados.
- Armazenando informações de transação de thread.
Como usar ThreadLocal?
Vejamos um exemplo simples.public static void main(String[] args) {
//Создаем ThreadLocal
ThreadLocal<String> local = new ThreadLocal<>();
//Создаем новый класс Random
Random random = new Random();
//Создаем 5 потоков
IntStream.range(0, 5).forEach(a-> new Thread(()-> {
//Присваиваем meaning каждому потоку
local.set(a+" "+random.nextInt(100));
System.out.println("Thread number and its local value "+ local.get());
}).start());
}
No código acima, criamos uma classe ThreadLocal , criamos 5 threads, atribuímos um valor a ThreadLocal em cada thread e imprimimos. Ao produzir, obtemos:
O que há sob o capô?
Se você olhar com atenção, verá que existem dois métodos importantes em ThreadLocal neste exemplo de código.-
público T get() {}
-
conjunto de vazios públicos (valor T) {}
public void set(T value) {
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null)
map.set(this, value);
else
createMap(t, value);
}
O método setter primeiro obtém o thread atual e chama o método getMap() para obter a classe ThreadLocalMap . Se o mapa existir, considere o fluxo atual t como a chave, o parâmetro de entrada como o valor e defina o par {key:value} como map. Caso contrário, crie um mapa . Agora você pode ter uma pergunta - o que é ThreadLocalMap ?
static class ThreadLocalMap {
/**
* The entries in this hash map extend WeakReference, using
* its main ref field as the key (which is always a
* ThreadLocal object). Note that null keys (i.e. entry.get()
* == null) mean that the key is no longer referenced, so the
* entry can be expunged from table. Such entries are referred to
* as "stale entries" in the code that follows.
*/
static class Entry extends WeakReference<ThreadLocal<?>> {
/** The value associated with this ThreadLocal. */
Object value;
Entry(ThreadLocal<?> k, Object v) {
super(k);
value = v;
}
}
}
ThreadLocalMap é uma classe estática interna em ThreadLocal que define uma classe Entry para armazenar dados. Entry usa a instância ThreadLocal como chave e define o valor que passamos. Se isso parece muito confuso neste momento, lembre-se de que é a classe Entry em ThreadLocalMap que faz o armazenamento real dos valores. Para obter dados do ThreadLocal usamos o método getter :
public T get() {
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null) {
ThreadLocalMap.Entry e = map.getEntry(this);
if (e != null) {
@SuppressWarnings("unchecked")
T result = (T)e.value;
return result;
}
}
return setInitialValue();
}
No método getter , usaremos currentThread como chave para obter ThreadLocalMap . Então map irá getEntry() com base na instância ThreadLocal e retornará a instância Entry e então o valor armazenado. Aqui está um diagrama para ajudá-lo a descobrir:
-
Cada thread mantém uma referência a ThreadLocalMap .
-
ThreadLocalMap é uma classe estática interna de ThreadLocal e usa a classe Entry para armazenamento.
-
Uma chave ThreadLocalMap é uma instância de ThreadLocal e pode ter vários ThreadLocals .
-
O próprio ThreadLocal não armazena um valor, mas é uma chave para o thread que ajudará a obter o valor de ThreadLocalMap .
Classe de scanner em Java
Fonte: Medium Esta postagem irá ajudá-lo a se familiarizar com a classe Scanner em Java. A classe Scanner em Java é uma classe que usamos quando queremos obter um valor do usuário. A maneira mais fácil de entender isso é com exemplos, então vamos ver com mais clareza. Criar uma classe Scanner é uma das três etapas que executamos para obter um valor do usuário. O primeiro passo é criar um objeto da classe scanner.Scanner scan=new Scanner(System.in);
Agora temos um objeto scanner. Este objeto terá as propriedades Scanner da classe Scanner . Após o primeiro passo o usuário já pode inserir o valor desejado, mas se não orientarmos o usuário e exibirmos o valor no console ou na aplicação, não será muito bom em termos de usabilidade. Portanto, é melhor informar e orientar o usuário:
System.out.println("Please enter your name");
String name=scan.next();
System.out.println("Your Name:"+name);
Na primeira linha perguntamos ao usuário o que queremos dele. Na verdade, isso não tem nada a ver com o scanner, mas é sempre bom dar dicas aos usuários. Na segunda linha iremos atribuir o valor que o usuário insere nos dados e salvá-lo para podermos utilizá-lo posteriormente. Na última linha vemos que podemos utilizar o valor recebido do usuário a nosso critério. Vamos adicionar mais alguns detalhes ao nosso código:
System.out.println("Please enter your last name");
String lastName=scan.next();
System.out.println("Your Name " + name + " " + "Your Last Name" + lastName);
Basicamente, repetimos as duas linhas anteriores, pedimos o valor ao usuário e salvamos. Agora na última linha usamos dois valores que pegamos do usuário e que agora são usados juntos.
GO TO FULL VERSION