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个时,可能有些线程需要等待。
java并发编程基础——线程相关的类的更多相关文章
- Java并发编程基础-线程安全问题及JMM(volatile)
什么情况下应该使用多线程 : 线程出现的目的是什么?解决进程中多任务的实时性问题?其实简单来说,也就是解决“阻塞”的问题,阻塞的意思就是程序运行到某个函数或过程后等待某些事件发生而暂时停止 CPU 占 ...
- java并发编程基础——线程的创建
一.基础概念 1.进程和线程 进程:每个进程都有独立的代码和数据空间(进程上下文),进程间的切换会有较大的开销,一个进程包含1--n个线程.(进程是资源分配的最小单位) 线程:同一类线程共享代码和数据 ...
- java并发编程基础——线程池
线程池 由于启动一个线程要与操作系统交互,所以系统启动一个新的线程的成本是比较高的.在这种情况下,使用线程池可以很好的提升性能,特别是程序中涉及创建大量生命周期很短暂的线程时. 与数据库连接池类似,线 ...
- java并发编程基础——线程同步
线程同步 一.线程安全问题 如果你的代码所在的进程中有多个线程在同时运行,而这些线程可能会同时运行这段代码.如果每次运行结果和单线程运行的结果是一样的,而且其他的变量的值也和预期的是一样的,就是线程安 ...
- java并发编程基础——线程通信
线程通信 当线程在系统内运行时,程序通常无法准确的控制线程的轮换执行,但我们可以通过一些机制来保障线程的协调运行 一.传统的线程通信 传统的线程通信主要是通过Object类提供的wait(),noti ...
- Java并发编程基础
Java并发编程基础 1. 并发 1.1. 什么是并发? 并发是一种能并行运行多个程序或并行运行一个程序中多个部分的能力.如果程序中一个耗时的任务能以异步或并行的方式运行,那么整个程序的吞吐量和可交互 ...
- Java并发编程:线程池的使用
Java并发编程:线程池的使用 在前面的文章中,我们使用线程的时候就去创建一个线程,这样实现起来非常简便,但是就会有一个问题: 如果并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了, ...
- Java并发编程:线程池的使用(转)
Java并发编程:线程池的使用 在前面的文章中,我们使用线程的时候就去创建一个线程,这样实现起来非常简便,但是就会有一个问题: 如果并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了, ...
- Java并发编程:线程池的使用(转载)
转载自:https://www.cnblogs.com/dolphin0520/p/3932921.html Java并发编程:线程池的使用 在前面的文章中,我们使用线程的时候就去创建一个线程,这样实 ...
随机推荐
- CPU的自动调度矩阵乘法
CPU的自动调度矩阵乘法 这是一个有关如何对CPU使用自动调度程序的文档. 与依靠手动模板定义搜索空间的基于模板的autotvm不同,自动调度程序不需要任何模板.用户只需要编写计算声明,而无需任何调度 ...
- Java中List和Map的区别
一.List和Map 1.特点 (1).List 1.可以允许重复的对象. 2.可以插入多个null元素. 3.是一个有序容器,保持了每个元素的插入顺序,输出的顺序就是插入的顺序. 4.常用的实现类有 ...
- 【疑难杂症】高版本UG从老UI中获取汉字字符串后乱码的问题
结论:NXstring转换为char类型的时候导致了乱码 措施: 改前:string strA=Test001::test001StrName->ItemValue().GetText(); / ...
- Effective Fusion Factor in FPN for Tiny Object Detection
微小目标检测的FPN有效融合因子 摘要:基于FPN的检测器在一般物体检测方面取得了显著的进步,例如MS COCO和PASCAL VOC.然而,这些检测器在某些应用场景中会失败,例如微小物体检测.在本文 ...
- MySQL的可重复读级别能解决幻读问题吗?
之前在深入了解数据库理论的时候,了解到事务的不同隔离级别可能存在的问题.为了更好的理解所以在MySQL数据库中测试复现这些问题.关于脏读和不可重复读在相应的隔离级别下都很容易的复现了. 但是对于幻读, ...
- StackOverflow经典问题:代码中如何去掉烦人的“!=null"判空语句
问题 为了避免空指针调用,我们经常会看到这样的语句 if (someobject != null) { someobject.doCalc();} 最终,项目中会存在大量判空代码,多么丑陋繁冗!如何避 ...
- AIOps:企业运维新力量!
摘要:企业运维需求及挑战,来看看华为AIOps如何解决! 本文分享自华为云社区<[云驻共创]AIOps?企业运维新力量!>,原文作者:启明. 国际惯例,我们先介绍一下AIOps的概念:AI ...
- Pytest学习笔记4-assert断言
前言 pytest作为单元测试框架,自然少不了断言功能,用过unittest的人都知道,在unittest中有丰富的断言方法,比如assertEqual().assertIn().assertTrue ...
- JAVA设计模式(6:单例模式详解)
单例模式作为一种创建型模式,在日常开发中用处极广,我们先来看一一段代码: // 构造函数 protected Calendar(TimeZone var1, Locale var2) { this.l ...
- hive学习笔记之三:内部表和外部表
欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...