Simple analysis of the use of threadlocal classes in Java threading programming _java

Source: Internet
Author: User
Tags memory usage

I. Overview

What is threadlocal? In fact, Threadlocal is not a local implementation version of a thread, it is not a threads, but a threadlocalvariable (thread-local variables). Perhaps it would be more appropriate to name it Threadlocalvar. Thread-local variables (ThreadLocal) are very simple in fact, is to provide a copy of the variable value for each thread that uses the variable, and is a more specific thread binding mechanism in Java, where each thread can independently alter its own copy without conflict with the replica of the other thread.

From a thread's point of view, each thread maintains an implicit reference to its thread local variable copy, as long as the thread is active and the ThreadLocal instance is accessible, and all copies of its thread-local instances are garbage collected (unless there are other references to those replicas) after the threads have disappeared.

Data accessed through threadlocal is always related to the current thread, that is, the JVM binds a private local instance access space for each running thread, thus providing an isolation mechanism for concurrent access problems that often occur in a multithreaded environment.

How does threadlocal maintain a copy of a variable for each thread? In fact, the idea of implementation is very simple, in the Threadlocal class has a map, used to store a copy of each thread's variables.

To sum up, for multithreading resource sharing problem, synchronization mechanism adopts the way of "changing space with Time", and Threadlocal adopts the way of "changing time in Space". The former provides only one variable, allowing different threads to be queued for access, and the latter provides a variable for each thread so that it can be accessed simultaneously without affecting each other.

Second, the API description

ThreadLocal ()
Creates a thread-local variable.

T get ()
Returns the value in the current thread copy of this thread local variable, which is created and initialized if this is the first time a thread calls the method.

Protected T InitialValue ()
Returns the initial value of the current thread for this thread local variable. This method is called at most once per thread-local variable is obtained, the first time a thread accesses a variable using the Get () method. If the thread calls the set (T) method before the Get method, then the InitialValue method is not called in the thread.

If the implementation returns NULL only, or if the programmer wants to initialize a thread-local variable to a value other than NULL, you must create a subclass for ThreadLocal and override this method. Typically, anonymous inner classes are used. A typical implementation of InitialValue will invoke an appropriate construction method and return the newly constructed object.

void Remove ()
Removes the value of this thread local variable. This may help reduce the storage requirements for thread-local variables. If you access this thread local variable again, it will have its initialvalue by default.

void set (T value)
Sets the value in the current thread copy of this thread local variable to the specified value. Many applications do not require this functionality, and they rely only on the InitialValue () method to set the value of a thread-local variable.

The InitialValue method is generally overridden in a program to give a specific initial value.

Three or one. Understanding of Threadlocal

ThreadLocal, many places are called thread-local variables, and some places are called thread-local storage, in fact, the meaning is similar. Probably a lot of friends know that Threadlocal creates a copy for a variable in each thread, so each thread can access its own internal replica variable.

This sentence is literally easy to understand, but it's not so easy to really understand.

Let's take a look at an example first:

Class ConnectionManager {
   
  private static Connection connect = NULL;
   
  public static Connection OpenConnection () {
    if (connect = null) {
      connect = drivermanager.getconnection ();
    } return
    connect;
  }
   
  public static void CloseConnection () {
    if (connect!=null)
      connect.close ();
  }
}

Suppose there is such a database link management class, and this code is used in a single thread without any problems, but what if it is used in multiple threads? Obviously, there are thread-safety issues with Multithreading: First, 2 of these methods are not synchronized, and it is possible to create the connect multiple times in the OpenConnection method, and second, because connect is a shared variable, It is necessary to use synchronization to ensure thread safety when calling connect, because it is likely that one thread is using connect for database operations while another thread calls the CloseConnection close link.

Therefore, for thread-safe consideration, two methods of this code must be synchronized, and the place where the call to connect needs to be handled synchronously.

This will greatly affect program execution efficiency, because when a thread is using Connect for database operations, other threads have to wait.

So let's take a closer look at this question, does this place need to share the connect variable? In fact, it's not necessary. If there is a connect variable in each thread, access to the connect variable between the threads is actually not dependent, that is, a thread does not need to care whether other threads have modified the connect.

Here, there may be a friend who thinks that since you don't need to share this variable between threads, you can do this directly, creating a database link in each method that requires a database connection, and then releasing the connection after the method call is complete. Let's say this:

Class ConnectionManager {
   
  private Connection connect = null;
   
  Public Connection OpenConnection () {
    if (connect = null) {
      connect = drivermanager.getconnection ();
    }
    return connect;
  }
   
  public void CloseConnection () {
    if (connect!=null)
      connect.close ();
  }
}
 
 
Class dao{public
  void Insert () {
    ConnectionManager ConnectionManager = new ConnectionManager ();
    Connection Connection = Connectionmanager.openconnection ();
     
    Operation with connection
     
    connectionmanager.closeconnection ();
  }

There is really no problem with this, because each time a connection is created within the method, there is naturally no thread safety problem between threads. But this can have a fatal effect: causing the server to be very stressful and severely impacting program execution performance. Because database connections need to be turned on and off frequently in a method, this does not seriously affect program execution efficiency, and can also cause server pressure to be enormous.

In this case, the use of threadlocal is more suitable, because the threadlocal in each thread will create a copy of the variable, that is, each thread will have a variable inside, and anywhere within the thread can be used, the threads do not affect each other, As a result, there is no thread-safety problem and does not seriously affect program execution performance.

Note, however, that although threadlocal can solve the problem mentioned above, because a replica is created on each thread, consider its consumption of resources, such as memory usage that is larger than not using threadlocal.

Iv. examples

Create a bean that sets the bean properties through different thread objects to guarantee the independence of the individual thread bean objects.

/** * Created by the IntelliJ idea.  * User:leizhimin * date:2007-11-23 * time:10:45:02 * Student/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. 
  * User:leizhimin * date:2007-11-23 * time:10:53:33 * Multithreading test Program/public class Threadlocaldemo implements Runnable {
 
  Create a thread local variable studentlocal, in the back you will find 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 (); /** * Example Business method, used to test/public void Accessstudent () {//Get the name of the current thread String currentthreadname = thread.cur
    Rentthread (). GetName ();
    System.out.println (Currentthreadname + "is running!"); //Produces a random number and prints Random Random = new Random ();
    int age = Random.nextint (100);
    SYSTEM.OUT.PRINTLN ("thread" + Currentthreadname + "set Age to:" + age);
    Gets a Student object and inserts a random number of ages into the object's properties Student Student = Getstudent ();
    Student.setage (age);
    SYSTEM.OUT.PRINTLN ("thread" + Currentthreadname + "The" "The" "The" "the" "+ 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 () {//Gets the local thread variable and casts it to the 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 to the local thread variable studentlocal
      Student = new Student ();
    Studentlocal.set (student);
  return student;
 }
}


Run Result:

A is running! 
Thread A set age to:76 
B is running! 
Thread B Set age to:27 thread A-a-I-is:76 thread B-A-read- 
is:27 
Thread A second read age : 
thread B Second Read age is:27 


You can see that a, b two thread age prints at different times in exactly the same value. This program through magical threadlocal, not only to achieve multithreading concurrency, to take into account the security of data.

V. General steps for the use of threadlocal

1, in the multithreaded class (such as the Threaddemo Class), create a Threadlocal object threadxxx, to save the thread between the object that needs to be quarantined processing xxx.
2, in the Threaddemo class, create a method to obtain the data to be quarantined getxxx (), in the method to judge, if the Threadlocal object is null, should be new () an object of the isolation access type, and cast to the type to be applied.
3, in the Threaddemo class of the Run () method, through the GetXXX () method to obtain the data to be manipulated, so as to ensure that each thread corresponds to a data object, at any time the operation of this object.

  

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.