Example demonstration of ThreadLocal functionality in Java

  • 2021-08-16 23:45:21
  • OfStack

In addition to using synchronized In addition to synchronization symbols, in Java ThreadLocal Is another way to achieve thread safety. In the process of writing performance test cases, the simpler way is to use it directly synchronized Keyword that modifies objects, methods, and classes. But using synchronized Synchronization, which may affect the scalability and operational efficiency of the application. However, if you want to share objects among multiple threads and ensure thread safety, except for synchronized There is no particularly suitable method for testing.

In Java ThreadLocal Is another way to achieve thread safety, which does not meet synchronization requirements, but eliminates sharing by providing an explicit copy of Object for each thread. Because objects are no longer shared, synchronization is not required, which can improve the scalability and efficiency of applications.

In this article, we will introduce the related ThreadLocal Basic knowledge points, Demo ThreadLocal A simple example of.

Introduction to ThreadLocal

Many people have hardly used it ThreadLocal Class, because there are too few places to use in testing, and the performance of test scripts is generally high, far exceeding the processing power of the service under test, so even if all of them are used synchronized There won't be any problems.

But ThreadLocal There are many real usage scenarios, which is why they were added to the standard Java platform library. Although we know that in multithreaded programming tests, ThreadLocal There are not many applications, but I will do more practice in the later period and share it with you.

The following is an example of Java ThreadLocal Some well-known uses of class:

ThreadLocal Perfect for implementing per-thread singleton classes or per-thread context information (such as transaction ID). You can wrap any non-threaded object in a ThreadLocal And make its use thread-safe. ThreadLocal One of the classic examples of is sharing SimpleDateFormat . Due to SimpleDateFormat Is not thread-safe, so using a global formatter may not work properly, but using a per-thread formatter certainly works. ThreadLocal Another extension is provided Thread The method. If you want to retain information or pass information from one method call to another method, you can use the ThreadLocal To pass on. Because there is no need to modify any methods, great flexibility can be provided.

No two threads can see each other's ThreadLocal Variables. 1 in J2EE application server ThreadLocal The server uses the Java ThreadLocal Variable to track transactions and security context.

To avoid excessive switching costs when creating and sharing global instances, it makes sense to share heavy objects such as database connections as ThreadLocal.

ThreadLocal Demo Demo


package com.fun.ztest.java;

import com.fun.frame.SourceCode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;

/**
 * ThreadLocal Demonstration test class 
 */
public class FunTester extends SourceCode {

  public static Logger logger = LoggerFactory.getLogger(FunTester.class);

  /**
   *  This is the point , Pass ThreadLocal Class to rebuild thread-private objects 
   */
  private static final ThreadLocal<Object> format = new ThreadLocal() {

    @Override
    protected Object initialValue() {
      Object funTester = new Object();
      logger.info(" Initialize object , Thread : {}  Object : {}", Thread.currentThread().getName(), funTester.hashCode());
      return funTester;
    }
  };

  public static void main(String args[]) throws IOException, InterruptedException {
    for (int i = 0; i < 5; i++) {
      Thread t = new Thread(new Fun());
      t.start();
    }
  }

  /**
   *  Get an object 
   *
   * @return
   */
  public static Object get() {
    return format.get();
  }


  static class Fun implements Runnable {

    @Override
    public void run() {
      logger.info(" Thread : {}  Object : {}", Thread.currentThread().getName(), FunTester.get().hashCode());
    }


  }


}


Console output


INFO->  Current user: fv , IP : 10.60.193.37 Working directory: /Users/fv/Documents/workspace/fun/, System coding format :UTF-8, System Mac OS X Version :10.16
INFO->  Initialize object , Thread : Thread-1  Object : 347384150
INFO->  Initialize object , Thread : Thread-2  Object : 142607688
INFO->  Thread : Thread-1  Object : 347384150
INFO->  Thread : Thread-2  Object : 142607688
INFO->  Initialize object , Thread : Thread-3  Object : 1008357237
INFO->  Initialize object , Thread : Thread-4  Object : 559951532
INFO->  Thread : Thread-3  Object : 1008357237
INFO->  Thread : Thread-4  Object : 559951532
INFO->  Initialize object , Thread : Thread-5  Object : 748958847
INFO->  Thread : Thread-5  Object : 748958847

Process finished with exit code 0

If you look at the output of the above program, you will find that when different threads call ThreadLocal Class get() Method instead of calling it initialValue() Method, the method creates a Object Gets or sets the mutex instance object of the. Due to Object It is not shared between threads and is essentially fully thread-safe locally to the thread that created its own thread-safe object or method.

ThreadLocal knowledge points

ThreadLocal of Java was introduced on JDK 1.2, but later generalized in JDK 1.4 to introduce type safety on ThreadLocal variables. ThreadLocal is commonly used with Thread1, and all code executed by Thread can access ThreadLocal variables, but two threads cannot see each other's ThreadLocal variables. Each thread has a mutex copy of the ThreadLocal variable, which is garbage collected only after the thread completes or dies (normally or due to any exception), because these ThreadLocal variables are not referenced by any other thread. ThreadLocal variables in Java are typically private static fields in the class, and their state is maintained in Thread.

Don't misunderstand that ThreadLocal is an alternative to Synchronization, it all depends on your own programming. If the design allows each thread to have its own copy of the object, you can use ThreadLocal.

Use in the project

Here, a class that handles requestid, which is used by ThreadLocal, can guarantee that each request has only 1 trace token.


public class TraceKeyHolder {
  private static ThreadLocal<String> threadLocal = new ThreadLocal();

  public TraceKeyHolder() {
  }

  public static String getTraceKey() {
    return (String)threadLocal.get();
  }

  public static void setTraceKey(String traceKey) {
    threadLocal.set(traceKey);
  }

  public static void clear() {
    threadLocal.remove();
  }
}

The above is the ThreadLocal feature demonstration example in Java details, more information about Java ThreadLocal features please pay attention to other related articles on this site!


Related articles: