欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

ThreadLocal类的使用

程序员文章站 2022-06-02 15:28:19
...

1.ThreadLocal 的使用

1.ThreadLocal 的作用, 它可以解决多线程的数据安全问题。
ThreadLocal 它可以给当前线程关联一个数据(可以是普通变量, 可以是对象, 也可以是数组, 集合)
ThreadLocal 的特点:

  1. ThreadLocal 可以为当前线程关联一个数据。 (它可以像 Map 一样存取数据, key 为当前线程)
  2. 每一个 ThreadLocal 对象, 只能为当前线程关联一个数据, 如果要为当前线程关联多个数据, 就需要使用多个ThreadLocal 对象实例。且每个 ThreadLocal 对象实例定义的时候, 一般都是 static 类型
  3. ThreadLocal 中保存数据, 在线程销毁后。 会由 JVM 虚拟自动释放。

2.code

public class OrderService {
public void createOrder(){
String name = Thread.currentThread().getName();
System.out.println("OrderService 当前线程[" + name + "]中保存的数据是: " +
ThreadLocalTest.threadLocal.get());
new OrderDao().saveOrder();
}
} 

public class OrderDao {
public void saveOrder(){
String name = Thread.currentThread().getName();
System.out.println("OrderDao 当前线程[" + name + "]中保存的数据是: " +
ThreadLocalTest.threadLocal.get());
}
} 

public class ThreadLocalTest {
// public static Map<String,Object> data = new Hashtable<String,Object>();
public static ThreadLocal<Object> threadLocal = new ThreadLocal<Object>();
private static Random random = new Random();
public static class Task implements Runnable {
@Override
public void run() {
// 在 Run 方法中, 随机生成一个变量(线程要关联的数据) , 然后以当前线程名为 key 保存到 map 中
Integer i = random.nextInt(1000);
// 获取当前线程名
String name = Thread.currentThread().getName();
System.out.println("线程["+name+"]生成的随机数是: " + i);
// data.put(name,i);
threadLocal.set(i);
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
} 
new OrderService().createOrder();
// 在 Run 方法结束之前, 以当前线程名获取出数据并打印。 查看是否可以取出操作
// Object o = data.get(name);
Object o = threadLocal.get();
System.out.println("在线程["+name+"]快结束时取出关联的数据是: " + o);
}
} 
public static void main(String[] args) {
for (int i = 0; i < 3; i++){
new Thread(new Task()).start();
}
}
}

3.使用ThreadLocala来处理项目事务

ThreadLocal类的使用
注意点:在ThreadLocal中获取连接(没有的话,则先创建conn放入【conns.set()】本地线程中),获取【conns.get()】之后进行事务的操作【操作过程中的DAO不能关闭conn,且将得到的exception往外抛】,之后再事务结束的serviceservlet进行事务的提交或接受异常回滚,关闭conn,并将本地线程conns.remove(),目的是释放线程到线程池中。

4.Filter结合ThreadLocal可以实现对整个项目的事务回滚

ThreadLocal类的使用
注意:回滚的Exception必须全部往外抛,知道Tomcat接收到异常,并且在web.xml中配置错误信息,才能显示出页面错误提示

<filter>
<filter-name>TransactionFilter</filter-name>
<filter-class>com.atguigu.filter.TransactionFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>TransactionFilter</filter-name>
<!-- / * 表示当前工程下所有请求 -->
<url-pattern>/ * </url-pattern>
</filter-mapping>
相关标签: java_web java