java并发编程基础——线程相关的类
线程相关类
java还为线程安全提供了一些工具类。
一、ThreadLocal类(Thread Local Variable)
ThreadLocal类,是线程局部变量的意思。功用非常简单,就是为每一个使用该变量的线程提供一个变量值的副本,使没一个线程都可以独立的改变自己的副本,而不会和其他副本冲突。
ThreadLocal提供了3个public方法
T get();返回此线程局部变量中当前线程副本中的值
void remove():删除此线程局部变量中当前线程的值
void set(T value):设置此线程局部变量中当前线程副本中的值
ThreadLocal也是为了解决多线程中对同一变量访问的冲突。普通的同步机制中是通过对象加锁来实现对同一变量的安全访问。
ThreadLocal从另一角度来解决多线程的并发,它是将需要并发访问的资源复制成多份,每个线程拥有一份资源,没必要对该变量进行同步了。
ThreadLocal并不能代替同步机制,两者的问题领域不同,同步机制是为了同步多个线程对相同的资源进行并发访问,是多线程之间进行通信的有效方式。ThreadLocal是为了隔离多个线程的数据共享,从根本上避免多个线程之间对共享资源的竞争。
最常见的ThreadLocal使用场景为 用来解决 数据库连接、Session管理等。
下面小程序说明了ThreadLocal能达到在每个线程中创建变量副本的效果:
package threadtest; public class ThreadTest implements Runnable{ private ThreadLocal<Integer> i =new ThreadLocal<>(); public int getI() { return i.get(); } public void setI(int i) { this.i.set(i); } @Override public void run() { for(i.set(0);i.get()<100;i.set(i.get()+1)) { System.out.println(Thread.currentThread().getName() + "--------->" + i.get()); } } public static void main(String[] args) { //两个线程,各自打印各自的值 ThreadTest tt = new ThreadTest(); Thread t1 = new Thread(tt,"t1"); Thread t2 = new Thread(tt,"t2"); t1.start(); t2.start(); } }
结果:i变量两个线程各自不影响
t1--------->0 t2--------->0 t1--------->1 t2--------->1 t1--------->2 t2--------->2 t1--------->3 t2--------->3 ... t2--------->94 t2--------->95 t2--------->96 t2--------->97 t2--------->98 t2--------->99 t1--------->15 t1--------->16 t1--------->17 t1--------->18 ... t1--------->97 t1--------->98 t1--------->99
二、包装线程不安全的集合
Java集合中ArrayList,LinkedList,HashSet,TreeSet,HashMap,TreeMap等都是线程不安全的,就是多个线程并发向这些集合中存取数据,可能会破坏数据的完整性。
如果要多线程访问这些集合,就需要包装下,需要用到Collections提供的静态方法把这些集合包装成安全的集合,方法如下:
static <T> Collection<T> synchronizedCollection(Collection<T> c)
static <T> List<T> synchronizedList(List<T> list)
static <K,V> Map<K,V> synchronizedMap(Map<K,V> m)
static <T> Set<T> synchronizedSet(Set<T> s)
static <K,V> SortedMap<K,V> synchronizedSortedMap(SortedMap<K,V> m)
static <T> SortedSet<T> synchronizedSortedSet(SortedSet<T> s)
//将ArrayList包装成安全的 List<String> l =Collections.synchronizedList(new ArrayList<String>());
三、线程安全的集合类
Java5开始,java.util.concurrent包下提供了大量支持高并发访问的集合接口和实现类
主要分为两类:
以Concurrent开头的集合类,如:ConcurrentHashMap,ConcurrentSkipListMap,ConcurrentSkipListSet,ConcurrentLinkedQueue,ConcurrentLinkedDeque
以CopyOnWrite开头的集合类,如: CopyOnWriteArrayList,CopyOnWriteArraySet.
其中Concurrent开头的集合类代表了并发访问的集合,支持多线程并发写入访问,这些写入程序的所有操作都是线程安全的,但读取不会锁定。
当多个线程共享访问一个公共集合时,ConcurrentLinkedQueue是一个不错的选择。ConcurrentLinkedQueue实现了多线程的高效访问,个线程访问时无需等待
在默认情况下ConcurrentHashMap支持16个线程并发写入,超过16个时,可能有些线程需要等待。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具