search
HomeJavajavaTutorialHow to use the java.lang.ThreadLocal class

How to use the java.lang.ThreadLocal class

May 05, 2023 pm 08:43 PM
javathreadlocal

I. Overview

What is ThreadLocal? In fact, ThreadLocal is not a local implementation version of a thread. It is not a Thread, but a threadlocal variable (thread local variable). Maybe it would be more appropriate to name it ThreadLocalVar. The actual function of thread local variables (ThreadLocal) is very simple. It is to provide a copy of the variable value for each thread that uses the variable. It is a special thread binding mechanism in Java that allows each thread to independently Change your own copy without conflicting with other threads' copies.

From a thread's perspective, each thread maintains an implicit reference to its copy of a thread-local variable as long as the thread is active and the ThreadLocal instance is accessible; after the thread disappears, all copies of its thread-local instance will be Garbage collection (unless there are other references to these copies).

Data accessed through ThreadLocal is always related to the current thread. That is to say, the JVM binds a private local instance access space to each running thread, thus providing a solution for concurrent access problems that often occur in multi-threaded environments. An isolation mechanism.

How does ThreadLocal maintain a copy of variables for each thread? In fact, the implementation idea is very simple. There is a Map in the ThreadLocal class, which is used to store a copy of the variables of each thread.

To sum up, for the problem of multi-thread resource sharing, the synchronization mechanism adopts the method of "exchanging time for space", while ThreadLocal adopts the method of "exchanging space for time". The former only provides a copy of the variable for different threads to queue for access, while the latter provides a copy of the variable for each thread, so it can be accessed at the same time without affecting each other.

2. API Description

ThreadLocal()

Create a thread local variable.

T get()

Returns the value in the current thread's copy of this thread-local variable, which is created and initialized if this is the first time the thread calls this method.

protected T initialValue()

Returns the current thread's initial value for this thread-local variable. This method is called at most once per thread access to obtain each thread-local variable, that is, when the thread first accesses the variable using the get() method. If the thread calls the set(T) method before the get method, the initialValue method will not be called again in the thread.

If this implementation simply returns null; if the programmer wishes to initialize thread-local variables to a value other than null, the programmer must subclass ThreadLocal and override this method. Typically, anonymous inner classes will be used. A typical implementation of initialValue will call an appropriate constructor and return the newly constructed object.

void remove()

Removes the value of this thread-local variable. This may help reduce storage requirements for thread-local variables. If this thread-local variable is accessed again, it will have its initialValue by default.

void set(T value)

Sets the value in the current thread's copy of this thread-local variable to the specified value. Many applications do not require this functionality and rely only on the initialValue() method to set the value of thread-local variables.

In programs, the initialValue method is generally overridden to give a specific initial value.

3. Typical examples

1. Hiberante’s Session tool class HibernateUtil

This class is the HibernateUtil class in Hibernate's official documentation and is used for session management.

public class HibernateUtil {

private static Log log = LogFactory.getLog(HibernateUtil.class);

private static final SessionFactory sessionFactory; //Define SessionFactory

static {

try {

//Create SessionFactory

through the default configuration file hibernate.cfg.xml sessionFactory = new Configuration().configure().buildSessionFactory();

} catch (Throwable ex) {

log.error("Initialization of SessionFactory failed!", ex);

throw new ExceptionInInitializerError(ex);

}

}

//Create thread local variable session to save Hibernate's Session

public static final ThreadLocal session = new ThreadLocal();

/**

* Get the Session

in the current thread * @return Session

* @throws HibernateException

*/

public static Session currentSession() throws HibernateException {

Session s = (Session) session.get();

// If the Session is not open yet, open a new Session

if (s == null) {

s = sessionFactory.openSession();

session.set(s); //Save the newly opened Session into thread local variables

}

return s;

}

public static void closeSession() throws HibernateException {

//Get thread local variables and cast to Session type

Session s = (Session) session.get();

session.set(null);

if (s != null)

s.close();

}

}

In this class, since the initialValue() method of ThreadLocal is not overridden, the thread local variable session is created for the first time and its initial value is null. When currentSession() is called for the first time, the get() method of the thread local variable is also null. . Therefore, the session is judged. If it is null, a new Session is opened and saved in the thread local variable session. This step is very critical. This is also the object created by "public static final ThreadLocal session = new ThreadLocal()" The reason why session can be coerced into a Hibernate Session object.

2. Another example

Create a Bean and set the Bean properties through different thread objects to ensure the independence of each thread Bean object.

/**

* Created by IntelliJ IDEA.

* User: leizhimin

* Date: 2007-11-23

* Time: 10:45:02

* 学生

*/

public class Student {

private int age = 0; //Age

public int getAge() {

return this.age;

}

public void setAge(int age) {

this.age = age;

}

}

/**

* Created by IntelliJ IDEA.

* User: leizhimin

* Date: 2007-11-23

* Time: 10:53:33

* Test program under multi-threading

*/

public class ThreadLocalDemo implements Runnable {

//Create the thread local variable studentLocal, which you will find later to save the Student object

private final static ThreadLocal studentLocal = new ThreadLocal();

public static void main(String[] agrs) {

ThreadLocalDemo td = new ThreadLocalDemo();

Thread t1 = new Thread(td, "a");

Thread t2 = new Thread(td, "b");

t1.start();

t2.start();

}

public void run() {

accessStudent();

}

/**

* Sample business method for testing

*/

public void accessStudent() {

//Get the name of the current thread

String currentThreadName = Thread.currentThread().getName();

System.out.println(currentThreadName " is running!");

//Generate a random number and print

Random random = new Random();

int age = random.nextInt(100);

System.out.println("thread " currentThreadName " set age to:" age);

//Get a Student object and insert the random age into the object attribute

Student student = getStudent();

student.setAge(age);

System.out.println("thread " currentThreadName " first read age is:" student.getAge());

try {

Thread.sleep(500);

}

catch (InterruptedException ex) {

ex.printStackTrace();

}

System.out.println("thread " currentThreadName " second read age is:" student.getAge());

}

protected Student getStudent() {

//Get local thread variables and cast them to Student type

Student student = (Student) studentLocal.get();

//When the thread executes this method for the first time, studentLocal.get() must be null

if (student == null) {

//Create a Student object and save it to the local thread variable studentLocal

student = new Student();

studentLocal.set(student);

}

return student;

}

}

operation result:

a is running!

thread a set age to:76

b is running!

thread b set age to:27

thread a first read age is:76

thread b first read age is:27

thread a second read age is:76

thread b second read age is:27

It can be seen that the values ​​printed by the two threads age at different times are exactly the same. This program uses ThreadLocal to achieve multi-thread concurrency while taking into account data security.

4. Summary

ThreadLocal is used mainly to solve the problem of data inconsistency due to concurrency in multi-threads. ThreadLocal provides a copy of the data that is accessed concurrently in each thread, and runs the business by accessing the copy. This consumes memory, greatly reduces the performance consumption caused by thread synchronization, and also reduces the complexity of thread concurrency control. Spend.

ThreadLocal cannot use atomic types, only Object types. The use of ThreadLocal is much simpler than synchronized.

Both ThreadLocal and Synchonized are used to solve multi-threaded concurrent access. But there is an essential difference between ThreadLocal and synchronized. Synchronized uses a lock mechanism so that a variable or code block can only be accessed by one thread at a time. ThreadLocal provides a copy of the variable for each thread, so that each thread does not access the same object at a certain time, thus isolating the data sharing of data by multiple threads. Synchronized is just the opposite. It is used to obtain data sharing when communicating between multiple threads.

Synchronized is used for data sharing between threads, while ThreadLocal is used for data isolation between threads.

Of course, ThreadLocal cannot replace synchronized, they deal with different problem domains. Synchronized is used to implement synchronization mechanism and is more complex than ThreadLocal.

5. General steps for using ThreadLocal

1. In a multi-threaded class (such as the ThreadDemo class), create a ThreadLocal object threadXxx to save the object xxx that needs to be isolated between threads.

2. In the ThreadDemo class, create a method getXxx() to obtain the data to be accessed in isolation. Judge in the method that if the ThreadLocal object is null, you should new() an object of the isolation access type and force it to be applied. type.

3. In the run() method of the ThreadDemo class, obtain the data to be operated through the getXxx() method. This ensures that each thread corresponds to a data object, and this object is operated at any time.

The above is the detailed content of How to use the java.lang.ThreadLocal class. For more information, please follow other related articles on the PHP Chinese website!

Statement
This article is reproduced at:亿速云. If there is any infringement, please contact admin@php.cn delete
What are the advantages of using bytecode over native code for platform independence?What are the advantages of using bytecode over native code for platform independence?Apr 30, 2025 am 12:24 AM

Bytecodeachievesplatformindependencebybeingexecutedbyavirtualmachine(VM),allowingcodetorunonanyplatformwiththeappropriateVM.Forexample,JavabytecodecanrunonanydevicewithaJVM,enabling"writeonce,runanywhere"functionality.Whilebytecodeoffersenh

Is Java truly 100% platform-independent? Why or why not?Is Java truly 100% platform-independent? Why or why not?Apr 30, 2025 am 12:18 AM

Java cannot achieve 100% platform independence, but its platform independence is implemented through JVM and bytecode to ensure that the code runs on different platforms. Specific implementations include: 1. Compilation into bytecode; 2. Interpretation and execution of JVM; 3. Consistency of the standard library. However, JVM implementation differences, operating system and hardware differences, and compatibility of third-party libraries may affect its platform independence.

How does Java's platform independence support code maintainability?How does Java's platform independence support code maintainability?Apr 30, 2025 am 12:15 AM

Java realizes platform independence through "write once, run everywhere" and improves code maintainability: 1. High code reuse and reduces duplicate development; 2. Low maintenance cost, only one modification is required; 3. High team collaboration efficiency is high, convenient for knowledge sharing.

What are the challenges in creating a JVM for a new platform?What are the challenges in creating a JVM for a new platform?Apr 30, 2025 am 12:15 AM

The main challenges facing creating a JVM on a new platform include hardware compatibility, operating system compatibility, and performance optimization. 1. Hardware compatibility: It is necessary to ensure that the JVM can correctly use the processor instruction set of the new platform, such as RISC-V. 2. Operating system compatibility: The JVM needs to correctly call the system API of the new platform, such as Linux. 3. Performance optimization: Performance testing and tuning are required, and the garbage collection strategy is adjusted to adapt to the memory characteristics of the new platform.

How does the JavaFX library attempt to address platform inconsistencies in GUI development?How does the JavaFX library attempt to address platform inconsistencies in GUI development?Apr 30, 2025 am 12:01 AM

JavaFXeffectivelyaddressesplatforminconsistenciesinGUIdevelopmentbyusingaplatform-agnosticscenegraphandCSSstyling.1)Itabstractsplatformspecificsthroughascenegraph,ensuringconsistentrenderingacrossWindows,macOS,andLinux.2)CSSstylingallowsforfine-tunin

Explain how the JVM acts as an intermediary between the Java code and the underlying operating system.Explain how the JVM acts as an intermediary between the Java code and the underlying operating system.Apr 29, 2025 am 12:23 AM

JVM works by converting Java code into machine code and managing resources. 1) Class loading: Load the .class file into memory. 2) Runtime data area: manage memory area. 3) Execution engine: interpret or compile execution bytecode. 4) Local method interface: interact with the operating system through JNI.

Explain the role of the Java Virtual Machine (JVM) in Java's platform independence.Explain the role of the Java Virtual Machine (JVM) in Java's platform independence.Apr 29, 2025 am 12:21 AM

JVM enables Java to run across platforms. 1) JVM loads, validates and executes bytecode. 2) JVM's work includes class loading, bytecode verification, interpretation execution and memory management. 3) JVM supports advanced features such as dynamic class loading and reflection.

What steps would you take to ensure a Java application runs correctly on different operating systems?What steps would you take to ensure a Java application runs correctly on different operating systems?Apr 29, 2025 am 12:11 AM

Java applications can run on different operating systems through the following steps: 1) Use File or Paths class to process file paths; 2) Set and obtain environment variables through System.getenv(); 3) Use Maven or Gradle to manage dependencies and test. Java's cross-platform capabilities rely on the JVM's abstraction layer, but still require manual handling of certain operating system-specific features.

See all articles

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

Video Face Swap

Video Face Swap

Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Tools

Safe Exam Browser

Safe Exam Browser

Safe Exam Browser is a secure browser environment for taking online exams securely. This software turns any computer into a secure workstation. It controls access to any utility and prevents students from using unauthorized resources.

EditPlus Chinese cracked version

EditPlus Chinese cracked version

Small size, syntax highlighting, does not support code prompt function

SublimeText3 Linux new version

SublimeText3 Linux new version

SublimeText3 Linux latest version

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

PhpStorm Mac version

PhpStorm Mac version

The latest (2018.2.1) professional PHP integrated development tool