Spring mvcスレッドセキュリティthreadLocal

7265 ワード

    Spring    DAO                      。            ,    ,  DAO                  。
, , 。 , 。
, , 。
, , , synchronized 。 Spring DAO , , 。
, , 。 , ? ThreadLocal!
ThreadLocal Spring , request Bean、 、 、AOP , 。 Spring ,ThreadLocal 。
ThreadLocal
JDK1.2 java.lang.ThreadLocal,ThreadLocal 。 。

ThreadLocal , “ ”。 ,ThreadLocal Thread, Thread , ThreadLocalVariable 。
ThreadLocal ,ThreadLocal , , 。
, , “Local” 。
Java , ( IBM IBM XLFORTRAN) 。 Java , ThreadLocal 。
, Java , Java 。
ThreadLocal
ThreadLocal , 4 , :
void set(Object value)

public Object get()

public void remove()
, , JDK5.0 。 , , , , 。
protected Object initialValue()
, protected , 。 , 1 get() set(Object) , 1 。ThreadLocal null。

, JDK5.0 ,ThreadLocal , ThreadLocal。API , API voidset(T value)、T get() T initialValue()。
ThreadLocal ? : ThreadLocal Map, ,Map , 。 :
// 1 SimpleThreadLocal
class SimpleThreadLocal {
private Map valueMap = Collections.synchronizedMap(new HashMap());
public void set(Object newValue) {
valueMap.put(Thread.currentThread(), newValue);//① ,
}
public Object get() {
Thread currentThread = Thread.currentThread();
Object o = valueMap.get(currentThread);// ②
if (o == null &&!valueMap.containsKey(currentThread)) {// ③ Map , Map
// 。
o = initialValue();
valueMap.put(currentThread, o);
}
return o;
}
public void remove() {
valueMap.remove(Thread.currentThread());
}
public Object initialValue() {
return null;
}
}

1 ThreadLocal , JDK ThreadLocal 。
TheadLocal
, ThreadLocal
package threadLocalDemo;
public class SequenceNumber {
//① ThreadLocal initialValue() ,
private static ThreadLocal seqNum =new ThreadLocal() {
public Integer initialValue() {
return 0;
}
};
//②
public int getNextNum() {
seqNum.set(seqNum.get() + 1);
return seqNum.get();
}
public static void main(String[] args)
{
SequenceNumber sn = new SequenceNumber();
// ③ 3 sn,
TestClient t1 = new TestClient(sn);
TestClient t2 = new TestClient(sn);
TestClient t3 = new TestClient(sn);
t1.start();
t2.start();
t3.start();
}
private static class TestClient extends Thread
{
private SequenceNumber sn;
public TestClient(SequenceNumber sn) {
this.sn = sn;
}
public void run()
{
for (int i = 0; i < 3; i++) {
// ④ 3
System.out.println("thread[" + Thread.currentThread().getName()+"]sn[" + sn.getNextNum() + "]");
}
}
}
}

ThreadLocal , , ① 。TestClient , ③ , 3 TestClient, SequenceNumber 。 , :
thread[Thread-2] sn[1]
thread[Thread-0] sn[1]
thread[Thread-1] sn[1]
thread[Thread-2] sn[2]
thread[Thread-0] sn[2]
thread[Thread-1] sn[2]
thread[Thread-2] sn[3]
thread[Thread-0] sn[3]
thread[Thread-1] sn[3]
, SequenceNumber , , , ThreadLocal 。
Thread
ThreadLocal ?ThreadLocal 。
, 。 , , , , 。
ThreadLocal 。ThreadLocal , 。 , 。ThreadLocal , , ThreadLocal。
ThreadLocal , JDK get() Object , 。 JDK5.0 , ThreadLocal , 9 2 JDK5.0 ThreadLocal
, , “ ” , ThreadLocal “ ” 。 , , , 。
Spring ThreadLocal
, Bean , Spring , Bean singleton 。 Spring Bean( RequestContextHolder、TransactionSynchronizationManager、LocaleContextHolder ) ThreadLocal , , Bean 。
Web 、 , , 。 , , 9?2 :

1
, ThreadLocal , , 。
Spring Bean :
3 TopicDao:
public class TopicDao {
private Connection conn;①
public void addTopic(){
Statement stat = conn.createStatement();②

}
}

① conn , addTopic() , TopicDao ( singleton)。 ThreadLocal conn “ ” :
4 TopicDao:
package threadLocalDemo;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
public class SqlConnection {
//① ThreadLocal Connection
private static ThreadLocalconnThreadLocal = newThreadLocal();
public static Connection getConnection() {
// ② connThreadLocal Connection Connection,
// 。
if (connThreadLocal.get() == null) {
Connection conn = getConnection();
connThreadLocal.set(conn);
return conn;
} else {
return connThreadLocal.get();
// ③
}
}
public voidaddTopic() {
// ④ ThreadLocal Connection
try {
Statement stat = getConnection().createStatement();
} catch (SQLException e) {
e.printStackTrace();
}
}
}