What is threadlocal in java

What is threadlocal in java

This class provides thread-local variables. These variables differ from their normal counterparts in that each thread that accesses one (via its get or set method) has its own, independently initialized copy of the variable. ThreadLocal instances are typically private static fields in classes that wish to associate state with a thread (e.g., a user ID or Transaction ID). For example, the class below generates unique identifiers local to each thread. A thread’s id is assigned the first time it invokes ThreadId.get() and remains unchanged on subsequent calls.

import java.util.concurrent.atomic.AtomicInteger; public class ThreadId < // Atomic integer containing the next thread ID to be assigned private static final AtomicInteger nextId = new AtomicInteger(0); // Thread local variable containing each thread's ID private static final ThreadLocalthreadId = new ThreadLocal() < @Override protected Integer initialValue() < return nextId.getAndIncrement(); >>; // Returns the current thread's unique ID, assigning it if necessary public static int get() < return threadId.get(); >>

Each thread holds an implicit reference to its copy of a thread-local variable as long as the thread is alive and the ThreadLocal instance is accessible; after a thread goes away, all of its copies of thread-local instances are subject to garbage collection (unless other references to these copies exist).

Читайте также:  David sklar php cookbook

Constructor Summary

Method Summary

Источник

What is threadlocal in java

This class provides thread-local variables. These variables differ from their normal counterparts in that each thread that accesses one (via its get or set method) has its own, independently initialized copy of the variable. ThreadLocal instances are typically private static fields in classes that wish to associate state with a thread (e.g., a user ID or Transaction ID). For example, the class below generates unique identifiers local to each thread. A thread’s id is assigned the first time it invokes ThreadId.get() and remains unchanged on subsequent calls.

import java.util.concurrent.atomic.AtomicInteger; public class ThreadId < // Atomic integer containing the next thread ID to be assigned private static final AtomicInteger nextId = new AtomicInteger(0); // Thread local variable containing each thread's ID private static final ThreadLocalthreadId = new ThreadLocal() < @Override protected Integer initialValue() < return nextId.getAndIncrement(); >>; // Returns the current thread's unique ID, assigning it if necessary public static int get() < return threadId.get(); >>

Each thread holds an implicit reference to its copy of a thread-local variable as long as the thread is alive and the ThreadLocal instance is accessible; after a thread goes away, all of its copies of thread-local instances are subject to garbage collection (unless other references to these copies exist).

Constructor Summary

Method Summary

Methods declared in class java.lang.Object

Constructor Detail

ThreadLocal

Method Detail

initialValue

Returns the current thread’s «initial value» for this thread-local variable. This method will be invoked the first time a thread accesses the variable with the get() method, unless the thread previously invoked the set(T) method, in which case the initialValue method will not be invoked for the thread. Normally, this method is invoked at most once per thread, but it may be invoked again in case of subsequent invocations of remove() followed by get() . This implementation simply returns null ; if the programmer desires thread-local variables to have an initial value other than null , ThreadLocal must be subclassed, and this method overridden. Typically, an anonymous inner class will be used.

Читайте также:  What is unit testing in java

withInitial

public static ThreadLocal withInitial​(Supplier supplier)

Creates a thread local variable. The initial value of the variable is determined by invoking the get method on the Supplier .

get

Returns the value in the current thread’s copy of this thread-local variable. If the variable has no value for the current thread, it is first initialized to the value returned by an invocation of the initialValue() method.

set

Sets the current thread’s copy of this thread-local variable to the specified value. Most subclasses will have no need to override this method, relying solely on the initialValue() method to set the values of thread-locals.

remove

Removes the current thread’s value for this thread-local variable. If this thread-local variable is subsequently read by the current thread, its value will be reinitialized by invoking its initialValue() method, unless its value is set by the current thread in the interim. This may result in multiple invocations of the initialValue method in the current thread.

Report a bug or suggest an enhancement
For further API reference and developer documentation see the Java SE Documentation, which contains more detailed, developer-targeted descriptions with conceptual overviews, definitions of terms, workarounds, and working code examples.
Java is a trademark or registered trademark of Oracle and/or its affiliates in the US and other countries.
Copyright © 1993, 2023, Oracle and/or its affiliates, 500 Oracle Parkway, Redwood Shores, CA 94065 USA.
All rights reserved. Use is subject to license terms and the documentation redistribution policy.

Источник

Кофе-брейк #160. Глубокое погружение в Java ThreadLocal. Класс Scanner в Java

Java-университет

Кофе-брейк #160. Глубокое погружение в Java ThreadLocal. Класс Scanner в Java - 1

Источник: Devgenios Сегодня вы узнаете о ThreadLocal — одном из распространенных классов, используемых при разработке Java-приложений.

Что такое ThreadLocal?

  1. Изоляция данных между потоками.
  2. Управление сессиями для подключения к базе данных.
  3. Хранение транзакционной информации потока.

Как использовать ThreadLocal?

 public static void main(String[] args) < //Создаем ThreadLocal ThreadLocallocal = new ThreadLocal<>(); //Создаем новый класс Random Random random = new Random(); //Создаем 5 потоков IntStream.range(0, 5).forEach(a-> new Thread(()-> < //Присваиваем значение каждому потоку local.set(a+" "+random.nextInt(100)); System.out.println("Thread number and its local value "+ local.get()); >).start()); > 

Кофе-брейк #160. Глубокое погружение в Java ThreadLocal. Класс Scanner в Java - 2

В приведенном выше коде мы создаем класс ThreadLocal , создаем 5 потоков, присваиваем значение ThreadLocal в каждом потоке и выводим на печать. При выводе получаем:

Что под капотом?

Метод setter сначала получает текущий поток и вызывает метод getMap() для получения класса ThreadLocalMap . Если map существует, возьмите текущий поток t в качестве ключа, входной параметр в качестве значения и установите пару в map. Если нет, то создайте map . Теперь у вас может появиться вопрос — что такое 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> < /** The value associated with this ThreadLocal. */ Object value; Entry(ThreadLocalk, Object v) < super(k); value = v; >> > 

ThreadLocalMap — это внутренний статический класс в ThreadLocal , определяющий класс Entry для хранения данных. Entry использует экземпляр ThreadLocal в качестве ключа и устанавливает значение, которое мы передаем. Если на данном этапе это звучит слишком запутанно, просто запомните, что именно класс Entry в ThreadLocalMap выполняет фактическое хранение значений. Чтобы получить данные из ThreadLocal , мы используем метод 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(); > 

Кофе-брейк #160. Глубокое погружение в Java ThreadLocal. Класс Scanner в Java - 3

В методе getter мы будем использовать currentThread в качестве ключа для получения ThreadLocalMap . Затем map получит getEntry() на основе экземпляра ThreadLocal и вернет экземпляр Entry , а затем сохраненное значение. Вот схема, которая поможет разобраться:

  1. Каждый поток поддерживает ссылку на ThreadLocalMap .
  2. ThreadLocalMap является внутренним статическим классом ThreadLocal и использует класс Entry для хранения.
  3. Ключ ThreadLocalMap является экземпляром ThreadLocal и может иметь несколько ThreadLocal .
  4. Сам ThreadLocal не хранит значение, но это ключ для потока, который поможет получить значение из ThreadLocalMap .

Обратите внимание, что лучше удалить ThreadLocal , чтобы избежать OOM (Out-of-Memory Error, ошибка нехватки памяти) из-за “слабой” ссылки в классе Entry .

Класс Scanner в Java

Кофе-брейк #160. Глубокое погружение в Java ThreadLocal. Класс Scanner в Java - 5

Источник: Medium Эта публикация поможет вам ознакомиться с классом Scanner в Java. Класс Scanner в Java — это класс, который мы используем, когда хотим получить значение от пользователя. Разобраться в нем легче всего на примерах, поэтому давайте разберем его более наглядно. Создание класса Scanner — это один из трех шагов, которые мы предпринимаем, чтобы получить значение от пользователя. Первый шаг — это создать объект из класса сканера.

 Scanner scan=new Scanner(System.in); 

Теперь у нас есть объект сканера. Этот объект будет иметь свойства Scanner из класса Scanner . После первого шага пользователь уже может ввести желаемое значение, но если мы не направим пользователя и не отобразим значение в консоли или в приложении, это будет не очень хорошо с точки зрения удобства. Поэтому лучше проинформировать и направить пользователя:

 System.out.println("Please enter your name"); String name=scan.next(); System.out.println("Your Name:"+name); 

В первой строке мы спрашиваем пользователя, что мы от него хотим. На самом деле это не имеет ничего общего со сканером, но всегда полезно давать подсказки своим юзерам. Во второй строке мы присвоим значение, которое пользователь введёт в данные, и сохраним его, чтобы мы могли использовать его позже. В последней строке мы видим, что можем использовать полученное от пользователя значение по своему усмотрению. Давайте добавим в наш код еще несколько деталей:

 System.out.println("Please enter your last name"); String lastName=scan.next(); System.out.println("Your Name " + name + " " + "Your Last Name" + lastName); 

Собственно говоря, мы повторили предыдущие две строки, запросили значение у пользователя и сохранили его. Теперь в последней строке мы использовали два значения, которые взяли у пользователя, и которые теперь используются вместе.

Источник

Оцените статью