Java多线程之ThreadLocal
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了Java多线程之ThreadLocal,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含2732字,纯文字阅读大概需要4分钟。
内容图文
![Java多线程之ThreadLocal](/upload/InfoBanner/zyjiaocheng/792/4ac599df6635432ca949d7412c1d9f3c.jpg)
ThreadLocal简介
ThreadLocal是Java中的线程局部变量,用于存放线程的局部变量。
ThreadLocal为每个线程的中并发访问的数据提供一个副本,通过访问副本来运行业务,这样的结果是耗费了内存,但是确避免线程同步所带来性能消耗,也减少了线程并发控制的复杂度。
首先看一下ThreadLocal的API:
- get():返回此线程局部变量的当前线程副本中的值。
- protected T initialValue(): 返回此线程局部变量的当前线程的“初始值”。
- void remove(): 移除此线程局部变量当前线程的值。
- void set(T value): 将此线程局部变量的当前线程副本中的值设置为指定值。
可以看出ThreadLocal内部应该就是封装了一个Map,自己实现ThreadLocal:
public 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); //③如果在Map中不存在,放到Map中保存起来 if (o == null && !valueMap.containsKey(currentThread)) { o = initialValue(); valueMap.put(currentThread, o); } return o; } public void remove() { valueMap.remove(Thread.currentThread()); } public Object initialValue() { return null; } }
以上代码很好理解,JDK中的实现比这复杂,可以自行查看源码。
ThreadLocal基本使用
ThreadLocal对象通常用于防止对可变的单实例变量或全局变量进行共享。
当一个类中使用了static成员变量的时候,一定要多问问自己,这个static成员变量需要考虑线程安全吗?也就是说,多个线程需要独享自己的static成员变量吗?如果需要考虑,不妨使用ThreadLocal。
例如,在单线程应用程序中可能会维护一个全局的数据库连接,并在程序启动的时候初始化这个连接,从而避免在调用每个方法的时候都要传递一个Connection对象。由于JDBC的连接对象不一定时线程安全的,因此,当多线程应用程序在没有协同的情况下使用全局变量时,就是不是线程安全的。通过把JDBC的连接保存到ThreadLocal对象中,每个线程都会拥有自己的连接。
import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; public class ConnectionManager { private static ThreadLocal<Connection> connectionHolder = new ThreadLocal<Connection>() { @Override protected Connection initialValue() { Connection conn = null; try { conn = DriverManager.getConnection( "jdbc:mysql://localhost:3306/test", "username", "password"); } catch (SQLException e) { e.printStackTrace(); } return conn; } }; public static Connection getConnection() { return connectionHolder.get(); } public static void setConnection(Connection conn) { connectionHolder.set(conn); } }
ThreadLocal需要注意的点
只要使用了“池”(线程池、连接池),在使用ThreadLocal时,尤其需要注意,每个线程在使用ThreadLocal的时候,必须对ThreadLocal执行一次clear操作,避免出现线程污染问题。
线程池中的线程是重复利用的,只要线程还在,ThreadLocal线程本地变量会一直存在系统中,在JavaEE的服务器中尤为明显。
内容总结
以上是互联网集市为您收集整理的Java多线程之ThreadLocal全部内容,希望文章能够帮你解决Java多线程之ThreadLocal所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。