Threadlocal implementation of the principle, and the use of examples, to solve spring,hibernate non-web projects under lazy loading no session or session is closed (1)!__web

Source: Internet
Author: User
Tags static class

A version of JDK 1.2 provides java.lang.threadlocal,threadlocal to solve the problem of local variable independence for multithreaded routines ...

To view the API we can view the definition and method of threadlocal:

This class provides a thread-local (thread-local) variable. These variables are different from their normal counterparts because each thread that accesses a variable (through its Get or set method) has its own local variable, which is independent of the initialization copy of the variable. ThreadLocal instances are usually private static fields in a class that want to associate a state with a thread (for example, a user ID or a transaction ID).

For example, the following class generates a local identifier unique to each thread. The thread ID is allocated on the first call to Uniquethreadidgenerator.getcurrentthreadid () and is not changed in subsequent invocations.

Construction Method Summary
ThreadLocal ()
Creates a thread-local variable.
Method Summary
T Get ()
Returns the value in the current thread copy of this thread local variable.
Protected T InitialValue ()
Returns the "initial value" of the current thread for this thread local variable.
void Remove ()
Removes the value of the current thread for this thread local variable.
void Set (T value)
Sets the value in the current thread copy of this thread local variable to the specified value.

Remove ()

Removes the current thread value of this thread local variable to reduce memory footprint, which is a new method for JDK 5.0. It is important to note that when the thread ends, the local variable that should be thread is automatically garbage collected, so it is not necessary to explicitly call the method to purge the thread's local variables, but it can speed up the memory collection.

InitialValue ()

Returns the initial value of the thread's local variable, which is a protected method, apparently designed to allow subclasses to overwrite. This method is a deferred invocation method that executes only 1 times when the thread calls get () or set (Object) for the 1th time. The default implementation in Threadlocal returns a null directly. If the generic object is an integer, you can define an internal, overriding InitialValue() to return data of the integer type 0.

Threadlocal is not a so-called "local thread", but rather a processing of local variables in threads. It can be understood as: "Local thread variable (thread locally variable)"!

Thread local variables have been used in many languages, not Java original ... Many languages, such as IBM IBM XL FORTRAN, provide thread-local variables at the syntactic level.

The implementation principle of threadlocal is as follows:

Package cn.vicky; Import java.util.Collections; Import Java.util.HashMap; Import Java.util.Map; public class Realizethreadlocal {private map<string, object> Map = Collections.synchronizedmap (New hashmap< String, object> ()); public void Set (Object value) {map.put (Thread.CurrentThread (). GetName (), value);} public Object get () {String Threadnam E = Thread.CurrentThread (). GetName (); Object o = map.get (threadname); if (o = = null &&!map.containskey (threadname)) {o = InitialValue (); Map.put (ThreadName, O);} return o; public void Remove () {Map.Remove () Thread.CurrentThread (). GetName ()), Public Object InitialValue () {return null;}}

In JDK5.0, Threadlocal has supported generics, and the class name of the class has changed to threadlocal<t>. The principle of implementation is as follows:

Package cn.vicky; Import java.util.Collections; Import Java.util.HashMap; Import Java.util.Map; public class Realizethreadlocal2<t> {private Map<long, t> Map = Collections.synchronizedmap (New hashmap< Long, t> ()); public void Set (T value) {map.put (Thread.CurrentThread (). GetId (), value);} public T get () {Long ThreadID = Thread.curre Ntthread (). GetId (); T o = map.get (ThreadID); if (o = = null &&!map.containskey (ThreadID)) {o = InitialValue (); Map.put (ThreadID, O);} return o; public void Remove () {Map.Remove () Thread.CurrentThread (). GetName ()), Public T InitialValue () {return null;}}

How to use:

Package cn.vicky; The public class SequenceNumber {//Overrides the RealizeThreadLocal2 InitialValue () method by an anonymous inner class, specifying the corresponding initial value based on the generic type private static realizethreadlocal2<integer> seqnum = new realizethreadlocal2<integer> () {@Override public Integer InitialValue () {return 0;}}; Gets the next sequence value public int getnextnum () {Seqnum.set (Seqnum.get () + 1), return Seqnum.get (), and public static void main (string[ ] args {sequencenumber sn = new SequenceNumber ();//3 threads share sn, each produces serial number testthread TT1 = new Testthread (SN); Testthread tt2 = new Testthread (SN); Testthread tt3 = new Testthread (SN); thread T1 = new Thread (TT1); Thread t2 = new Thread (TT2); thread t3 = new Thread (TT3); T1.start (); T2.start (); T3.start (); } }

Package cn.vicky; public class Testthread implements Runnable {private sequencenumber sn; public testthread (SequenceNumber sn) {this.sn = sn public void Run () {//each thread hits 3 sequence values for (int i = 0; i < 3; i++) {System.out.println ("thread[" + thread.currentthread ( ). GetName () + "] sn[" + sn.getnextnum () + "]");}}

Print:

THREAD[THREAD-0] sn[1]
THREAD[THREAD-0] sn[2]
THREAD[THREAD-0] sn[3]
Thread[thread-2] sn[1]
Thread[thread-2] sn[2]
Thread[thread-2] sn[3]
THREAD[THREAD-1] sn[1]
THREAD[THREAD-1] sn[2]
THREAD[THREAD-1] sn[3]

Testthread tt1 = new Testthread (SN);
Testthread tt2 = new Testthread (SN);
Testthread tt3 = new Testthread (SN);

Output information, we find that each thread produces an ordinal number that shares the same sequencenumber (SN) instance, but they do not interfere with each other, but they produce separate serial numbers. This is because we provide a separate copy of each thread through the threadlocal!

Let's look at a simple example:

Package cn.vicky.chapt05; /** * * @author Vicky.H/public class ThreadLocalTest1 {/** implements static variables for each thread different **/private static THREADLOCAL&L T

    String> val = new threadlocal<string> ();

        public static class Thread1 extends Thread {private String name;
        Public Thread1 (String name) {this.name = name;
            public void Run () {System.out.println (name + "Initial value:" + val.get ());
            Val.set ("v[" + name + "]");
        SYSTEM.OUT.PRINTLN (name + "set after value:" + val.get ());

        } public static class Thread2 extends Thread {private String name;
        Public Thread2 (String name) {this.name = name;
            public void Run () {System.out.println (name + "Initial value:" + val.get ());
            Val.set ("v[" + name + "]");
        SYSTEM.OUT.PRINTLN (name + "set after value:" + val.get ());
      } public static void Main (string[] args) {Val.set ("1");  System.out.println ("Set value in Main program:" + Val.get ());
        (New Thread1 ("A1")). Start ();
        (New Thread1 ("A")). Start ();
    (New Thread2 ("B1")). Start (); ///Main program Set value: 1//a1 initial value: null//A1 Set Value: V[A1]//b1 initial value: null//a initial value: null//a Set Value: V[a]//B1 Set Value: V[B1]//Summary//threadlocal use field
The main solution is to solve the inconsistency problem of data data in multiple threads due to concurrency. 
Threadlocal provides a copy of the data that is concurrently accessed in each thread and runs the business by accessing the Vice, which results in memory savings that greatly reduce the performance consumption of thread synchronization and reduce the complexity of thread concurrency control.
Threadlocal cannot use atomic types, only object types are used. 
Threadlocal is much simpler to use than synchronized. Both threadlocal and synchonized are used to resolve multithreaded concurrent access. But there is an essential difference between threadlocal and synchronized. Synchronized is the mechanism by which a variable or block of code can only be accessed by one thread at a time. The threadlocal provides a copy of the variable for each thread, so that each thread is not accessing the same object at a given time, isolating multiple threads from data sharing. 
Synchronized, in contrast, is used to gain 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 does not replace synchronized, which handles different problem domains. 
Synchronized is used to implement synchronization mechanisms, more complex than threadlocal.
 }


 

Package cn.vicky.chapt05;

    /** * * @author Vicky.H/public class ThreadLocalTest2 {/** implements the static variables for each thread differently **/private static String Val;

        public static class Thread1 extends Thread {private String name;
        Public Thread1 (String name) {this.name = name;
            public void Run () {System.out.println (name + "Initial value:" + val);
            val = "v[" + name + "]";
        SYSTEM.OUT.PRINTLN (name + "set after value:" + val);

        } public static class Thread2 extends Thread {private String name;
        Public Thread2 (String name) {this.name = name;
            public void Run () {System.out.println (name + "Initial value:" + val);
            val = "v[" + name + "]";
        SYSTEM.OUT.PRINTLN (name + "set after value:" + val);
        } public static void Main (string[] args) {val = ' 1 ';
        System.out.println ("Set value in Main program:" + val);
        (New Thread1 ("A1")). Start (); (New Thread1 ("A")). Start ();
    (New Thread2 ("B1")). Start ();
 //Main program Set value: 1//a1 initial value: 1//a1 after setting value: V[A1]//a initial value: V[A1]//a Set value: V[a]//b1 initial value: V[a]//B1 Set value: V[B1]


 

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.