Why ThreadLocal?
In any case, to write a multithreaded security (Thread-safe) program is difficult, in order to allow the thread to share resources, must be careful to synchronize the shared resources, synchronization brings certain performance delays, on the other hand, in the process of synchronization, but also attention to the lock and release of objects, to avoid the deadlock, All sorts of factors make it difficult to write multithreaded programming. Try to think of the problem of multi-threaded shared resources from another perspective, since it is so difficult to share resources, simply do not share, why not create a copy of the resource for each thread. The way in which each thread accesses data is isolated, by giving each thread a specific space to hold the resource that is unique to the thread.
what is threadlocal.
As the name suggests, it is a local variable (thread-locally variable). Its function is very simple, for each thread that uses this variable provides a copy of the variable value, each thread can independently change its own copy, and not with the other threads of the replica conflict. From a thread's point of view, it's as if every thread owns the variable entirely.
Use scene to keep state with a thread (User-id, Transaction-id, Logging-id) to cache objects which you need Freque ntly
threadlocal classes implement thread-scoped shared variables
It is mainly composed of four methods InitialValue (), Get (), set (T), remove (), which is noteworthy is initialvalue (), the method is a protected method, obviously for subclass rewrite and deliberately implemented. This method returns the initial value of the current thread's local variable in the thread, which is a deferred invocation method that executes only 1 times when a thread calls get () or set (Object) for the 1th time. A true implementation in threadlocal returns a null directly:
The principle of threadlocal
Threadlocal is how to 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. For example, the following examples implement:
public class ThreadLocal
{
Private MAP values = Collections.synchronizedmap (new HashMap ());
Public Object Get ()
{
Thread curthread = Thread.CurrentThread ();
Object o = values.get (curthread);
if (o = = null &&!values.containskey (curthread))
{
o = InitialValue ();
Values.put (Curthread, O);
}
return o;
}
public void Set (Object newvalue)
{
Values.put (Thread.CurrentThread (), newvalue);
}
Public Object InitialValue ()
{
return null;
}
}
the use of ThreadLocal
Use method One:
Hibernate's documentation was seen in the section on making threadlocal Manage multithreaded access. The specific code is as follows
1. public static final ThreadLocal session = new ThreadLocal ();
2. public static session currentsession () {
3. Session S = (session) Session.get ();
4.//open a new session,if this session has none
5. if (s = = null) {
6. S = sessionfactory.opensession ();
7. Session.set (s);
8.}
return s;
9.}
We analyze it by line
1. Initializes a Threadlocal object, Threadlocal has three member method get (), set (), InitialValue ().
If InitialValue is not initialized, InitialValue returns NULL.
3. The session's get returns its corresponding thread internal variables based on the current thread, which is the net.sf.hibernate.Session we need (equivalent to each database connection). It is not safe to share database links in multi-threaded situations. Threadlocal ensures that each thread has its own s (Database connection).
5. If this thread was first accessed, naturally, s (database connection) would be null, and then create a session, specifically line 6.
6. Create a database connection instance s
7. Save the database connection s to threadlocal.
8. If the current thread has already accessed the database, get () from session gets () to obtain the connection instance that the thread last acquired.
Use Method Two
When you want to initialize a particular value to a thread, you need to implement the threadlocal subclass of your own and override the method, typically using an internal anonymous class to subclass Threadlocal, which is what the JDBC connection context creates in Easydbo:
public class jdbccontext{
private static Logger Logger = Logger.getlogger (Jdbccontext.class);
& Nbsp;private DataSource ds;
protected Connection Connection;
private Boolean isValid = true;
private static ThreadLocal jdbccontext;
private jdbccontext (DataSource ds) {
this.ds = ds;
CreateConnection ();
}
public static Jdbccontext Getjdbccontext (Javax.sql.DataSource DS)
{
if (jdbccontext==null) jdbccontext=new jdbccontextthreadlocal (DS);
jdbccontext context = (Jdbccontext) jdbccontext.get ();
if (context = = null) {
context = new Jdbccontext (DS);
return context;
}
private static class Jdbccontextthreadlocal extends ThreadLocal {
Public Javax.sql.DataSource DS;
Public jdbccontextthreadlocal (Javax.sql.DataSource DS)
{
This.ds=ds;
}
Protected synchronized Object InitialValue () {
return new Jdbccontext (DS);
}
}
}
Using the single case pattern, different threads invoke Getjdbccontext () to obtain their own jdbccontext, all by jdbccontextthreadlocal the built-in subclass to obtain the thread-local variables of the Jdbccontext object