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个时,可能有些线程需要等待。
最新文章
- #pg学习#postgresql的安装
- Hadoop学习笔记—9.Partitioner与自定义Partitioner
- ReportViewer报表
- Codeforces Round #252 (Div. 2) B. Valera and Fruits
- 【转】【SEE】基于SSE指令集的程序设计简介
- 【C++】动态内存与智能指针
- cvLoadImage函数解析 cvLoadImageM()函数
- Linq to SQL 简单增删改查
- linux的grep命令
- commons-beanutils使用
- python——python3.6环境搭建(Windows10,64位)
- 网络通信协议tcp,udp区别
- Qt创建任务栏进度条
- UFLDL 教程学习笔记(一)神经网络
- over()的用法
- RHEL7、CentOS7防火墙管理
- POJ 1125 Stockbroker Grapevine(最短路基础题)
- React Native超棒的LayoutAnimation(布局动画)
- [转载并收藏]JavaScript 疲劳终极指南:我们行业的真相
- 电子设备 Kindle如何删除书籍或漫画
热门文章
- 自监督学习(Self-Supervised Learning)多篇论文解读(上)
- 剑指 Offer 07. 重建二叉树
- selenium 隐式等待与显式等待
- 【TCP/IP】TCP详解笔记
- 【模拟8.03】斐波那契(fibonacci) (规律题)
- 08-ADMM算法
- sql数据库新建作业,新建步骤时报错从 IClassFactory 为 CLSID 为 {AA40D1D6-CAEF-4A56-B9BB-D0D3DC976BA2} 的 COM 组件创建实例失败,原因是出现以下错误: c001f011。 (Microsoft.SqlServer.ManagedDTS)
- mycat高可用-安全管理-监控 看这一篇就够了
- excel VBA构造函数就是这么简单
- 三、JavaSE语言基础之数据类型