开发者学堂课程【JDBC 数据库开发进阶:ThreadLocal】学习笔记,与课程紧密联系,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/32/detail/689
ThreadLocal
内容介绍:
一、ThreadLocal 简介
二、API说明
一、ThreadLocal 简介
ThreadLocal 用于保存某个线程共享变量。在 Java 中,每个线程对象都有一个ThreadLocal,其中 key 就是一个 ThreadLocal ,而 Object就是线程的共享变量。
对于同一个 static ThreadLocal ,不同的线程只能从中 get , set , remove 自己的变量,而不会影响其他线程的变量。
在 Java 的多线程编程中,为保证多个线程对共享变量的安全访问,通常会使用synchronized 来保证同一时刻只有一个线程对共享变量进行操作。
这种情况下可以将类变量放到 ThreadLocal 类型的对象中,使变量在每个线程中都有独立拷贝,不会出现一个线程读取变量时而被另一个线程修改的现象。
最常见的 ThreadLocal 使用场景为用来解决数据库连接、Session 管理等。
代码示例:
package cn.itcast.thread; import org.junit.Test; /**
*ThreadLocal对象的用法 *author cxf * */ public class Demo1 { @Test public void fun1() { ThreadLocal<string> tl = new ThreadLocal<string>( ); tl.set ( "hello");//存string s = tl.get ( );//取tl.remove() ; //删system.out.println (s) ; } } public void fun2{ final Map<Thread,string> map = new HashMap<Thread,string>( ) ; map.put (Thread.currentThreglo , "hello"); system.out.println (map.getThread.currentThread() ) ) ; new Thread () { public void run () { system.out.println (); } }.start() ; new Thread(o{ public void run () { tl.set( "内部类存"); system.out.println("内容类:" + tl.get()); } } try { Thread.sleep(1000) ; } catch (InterruptedException e) { //TODo Auto-generated catch blocke e.printstackTrace () ; } } /*ThreadLocal通常用在一个类的成员上*多个线程访问它时,每个线程都有自己的副本,互不干扰!*spring中把connection放到了ThreadLocal中!*明天我们会再次修改Jdbcutils类!*给它添加一个*/ class TL<T> { private Map<Thread,T> map = new HashMap<Thread,T>(); public void set ( .data) { //使用当前线程做keymap.put (Thread.currentThread() , data) ; } public Tget ( ) { return map.get (Thread.currentThread(); } public void remove () { map.remove(Thread.currentThread() ); } }
二、API说明
Threadlocal 类只有三个方法:
1.void set(T value):保存值;
将此线程局部变量的当前线程副本中的值设置为指定值。
许多应用程序不需要这项功能,它们只依赖于 initialValue() 方法来设置线程局部变量的值。在程序中一般都重写 initialValue 方法,以给定一个特定的初始值。
2.void remove():移除值
移除此线程局部变量的值。这可能有助于减少线程局部变量的存储需求。如果再次访问此线程局部变量,那么在默认情况下它将拥有其 initialValue 。
3.T get():获取值:
返回此线程局部变量的当前线程副本中的值,如果这是线程第一次调用该方法,则创建并初始化此副本。
4.protected T initialValue()
返回此线程局部变量的当前线程的初始值。最多在每次访问线程来获得每个线程局部变量时调用此方法一次,即线程第一次使用 get() 方法访问变量的时候。
如果线程先于 get 方法调用 set(T) 方法,则不会在线程中再调用 initialValue 方法。若该实现只返回 null ;如果程序员希望将线程局部变量初始化为 null 以外的某个值,则必须为 ThreadLocal 创建子类,并重写此方法。
通常,将使用匿名内部类。 initialValue 的典型实现将调用一个适当的构造方法,并返回新构造的对象。
代码示例:
import java.util.Random;
public class TestTools {
public static void main(String[] args) {
MyThread th1=new MyThread();
th1.start();
MyThread th2=new MyThread();
th2.start();
}
}
class Tools{
private static Random rand=new Random();
private static ThreadLocal th=new ThreadLocal<>();
{
th.set(rand.nextInt(100));
//这里设置的就是当前线程保存的共享变量,这个共享变量不是之前的多线程之间的共享变量,而是同一个线程在整个生命周期中,使用的共享变量。
}
public static int getNumber(){
return th.get();
}
}
class MyThread extends Thread{
public void run(){
Tools.setNumber();
for (int i = 0; i <5 ; i++) {
int number=Tools.getNumber();
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread()+":"+number);
}
}
}

