Java ThreadLocal 자세히 알아보기
출처: Devgenios 오늘은 Java 애플리케이션 개발에 사용되는 일반적인 클래스 중 하나인 ThreadLocal에 대해 알아봅니다.ThreadLocal이란 무엇입니까?
ThreadLocal 클래스는 스레드에 대한 지역 변수를 저장합니다. 이러한 변수는 서로 다른 스레드 간에 격리되어 있으며 자체 스레드에서만 액세스할 수 있습니다. ThreadLocal 사용 사례 :- 스레드 간 데이터를 격리합니다.
- 데이터베이스 연결을 위한 세션 관리.
- 스레드 트랜잭션 정보를 저장합니다.
ThreadLocal을 어떻게 사용하나요?
간단한 예를 살펴보겠습니다.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());
}
위 코드에서는 ThreadLocal 클래스를 만들고 , 5개의 스레드를 만들고, 각 스레드의 ThreadLocal 에 값을 할당 하고 인쇄합니다. 출력할 때 우리는 다음을 얻습니다:
후드 아래에는 무엇이 있나요?
자세히 살펴보면 이 코드 예제에서 ThreadLocal 에 두 가지 중요한 메서드가 있음 을 알 수 있습니다.-
공개 T get() {}
-
공개 무효 집합(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);
}
setter 메소드는 먼저 현재 스레드를 가져오고 getMap() 메소드를 호출하여 ThreadLocalMap 클래스를 가져옵니다 . map이 존재하는 경우 현재 스트림 t를 키로, 입력 매개변수를 값으로 사용하고 {key:value} 쌍을 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<ThreadLocal<?>> {
/** The value associated with this ThreadLocal. */
Object value;
Entry(ThreadLocal<?> k, Object v) {
super(k);
value = v;
}
}
}
ThreadLocalMap은 데이터를 저장하기 위한 Entry 클래스를 정의하는 ThreadLocal 의 내부 정적 클래스입니다 . Entry는 ThreadLocal 인스턴스를 키로 사용 하고 전달하는 값을 설정합니다. 이 시점에서 이것이 너무 혼란스럽게 들린다면, 실제로 값을 저장하는 것은 ThreadLocalMap 의 Entry 클래스라는 점을 기억하세요. 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();
}
getter 메소드 에서는 currentThread를 Key로 사용하여 ThreadLocalMap을 가져옵니다 . 그런 다음 map은 ThreadLocal 인스턴스를 기반으로 getEntry()를 수행 하고 Entry 인스턴스 와 저장된 값을 반환합니다. 이를 이해하는 데 도움이 되는 다이어그램은 다음과 같습니다.
-
각 스레드는 ThreadLocalMap 에 대한 참조를 유지합니다 .
-
ThreadLocalMap은 ThreadLocal 의 내부 정적 클래스 이며 저장을 위해 Entry 클래스를 사용합니다 .
-
ThreadLocalMap 키는 ThreadLocal의 인스턴스 이며 여러 ThreadLocal을 가질 수 있습니다 .
-
ThreadLocal 자체는 값을 저장하지 않지만 ThreadLocalMap 에서 값을 가져오는 데 도움이 되는 스레드의 키입니다 .
Java의 스캐너 클래스
출처: Medium 이 게시물은 Java의 Scanner 클래스에 익숙해지는 데 도움이 될 것입니다. Java의 Scanner 클래스는 사용자로부터 값을 얻고 싶을 때 사용하는 클래스입니다. 가장 쉽게 이해하는 방법은 예제를 이용하는 것이므로 좀 더 명확하게 살펴보겠습니다. 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);
기본적으로 이전 두 줄을 반복하고 사용자에게 값을 요청한 후 저장했습니다. 이제 마지막 줄에서 우리는 사용자로부터 가져와서 함께 사용되는 두 개의 값을 사용했습니다.
GO TO FULL VERSION