java并发系列——并发集合(一)
来源:互联网 发布:尽人事知天命下一句 编辑:程序博客网 时间:2024/05/17 04:22
一、介绍
在编程语言中,数据结构是一种能为计算机提供数据存储的元素,在java语言中,提供了集合框架,实现不同类型的数据结构的属性,类和接口等,可以应用于程序中。
在并发编程中,常用的大多数集合并不适用,因为它们没有控制数据
的并发访问,当多个并发线程访问同一个共享的数据结构时,会造成数据的不正确性。比如ArrayList,HashMap等。
(1)、当然java提供了可以在并发中使用的,不会出现问题且可保证数据一致的集合,可以分为如下两种:
1.阻塞集合
这种集合包括添加和删除数据的操作。如果操作不能立即进行,是因为集合已满或者为空,该程序将被阻塞,直到操作可以进行。
2.非阻塞集合
这种集合也包括添加和删除数据的操作。如果操作不能立即进行,这个操作将返回null值或抛出异常,但该线程将不会阻塞。
(2)、在并发编程中常用的一些集合列表:
- 非阻塞列表,使用ConcurrentLinkedDeque类。
- 阻塞列表,使用LinkedBlockingDeque类。
- 用在生产者与消费者数据的阻塞列表,使用LinkedTransferQueue类。
- 使用优先级排序元素的阻塞列表,使用PriorityBlockingQueue类。
- 存储延迟元素的阻塞列表,使用DelayQueue类。
- 非阻塞可导航的map,使用ConcurrentSkipListMap类。
- 随机数,使用ThreadLocalRandom类。
- 原子变量,使用AtomicLong和AtomicIntegerArray类。
二、非阻塞线程安全列表
(1)、列表(List):是最基本的线性集合元素,一个列表有不确定的元素数量,并且你可以添加、读取和删除任意位置上的元素。并发列表允许不同的线程在同一时刻对列表的元素进行添加或删除,而不会产生任何数据不一致(问题)。
(2)、ConcurrentLinekedQueue的使用,它是非阻塞的,若操作不能立即完成,它将根据此操作返回null或抛出异常。
下面来实现一个例子:
1.往列表中大量添加数据;
2.在同个列表中,进行数据的大量删除
程序实现:
1.增加任务类
public class AddTask implements Runnable { private ConcurrentLinkedDeque<String> list; public AddTask(ConcurrentLinkedDeque<String> list){ this.list=list; } @Override public void run() { String name=Thread.currentThread().getName(); for(int i=0;i<10000;i++){ list.add(name+":"+i); } }}
2.删除任务类
public class PollTask implements Runnable { private ConcurrentLinkedDeque<String> list; public PollTask(ConcurrentLinkedDeque<String> list){ this.list=list; } @Override public void run() { for(int i=0;i<5000;i++){ list.pollFirst(); list.pollLast(); } }}
3.测试类
@Test public void tesConcurrentLinkedDeque(){ ConcurrentLinkedDeque<String> list=new ConcurrentLinkedDeque<String>(); Thread threads[]=new Thread[100]; for(int i=0;i<threads.length;i++){ AddTask task=new AddTask(list); threads[i]=new Thread(task); threads[i].start(); } //使用join方法等待这些线程的完成 for(int i=0;i<threads.length;i++){ try { threads[i].join(); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.printf("Size of the List: %d\n",list.size()); for (int i=0; i<threads.length; i++){ PollTask task=new PollTask(list); threads[i]=new Thread(task); threads[i].start(); } System.out.printf("Main: %d PollTask threads have been launched\n",threads.length); //使用join方法等待这些线程的完成 for(int i=0;i<threads.length;i++){ try { threads[i].join(); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.printf("Size of the List: %d\n",list.size()); }
4、运行结果
(3)、 实现说明:
1.创建100个增加任务的线程(AddTask),将并发的list初始化到线程中
2.每个线程会在list的尾部插入新的元素,插入10000个元素,则list的大小为
3.用join方法等待线程创建完成,才开始执行下面操作
4.创建100个删除任务的线程(PollTask)
5.每个PollTask会执行pollFirst()删除头部元素,执行pollLast()删除尾部元素,若列表为空,则返回null
6.利用list的size()方法,打印列表元素中的量。
- java并发系列——并发集合(一)
- JAVA多线程—并发集合
- java并发--并发集合
- java并发系列——基本线程同步(一)
- Java并发编程系列(一)——Volatile
- java并发——多线程、线程池、并发集合
- Java并发编程系列(一):Java并发内存模型
- Java并发容器并发集合
- 【Java并发编程】并发集合
- java并发编程—— 一该不该用并发
- java并发系列:一线程常见问题
- 系统学习java高并发系列一
- Java并发(一)——Sychronized
- java学习(十二)—并发编程(一)
- java 并发集合
- Java并发集合类
- Java并发集合类
- java集合并发处理
- "launching delegate..." 停在 27%...
- RxJava的使用
- 开始在LeetCode上刷题(1-9)
- 横线滚动条
- 郭霖老师androidpn教学视频笔记
- java并发系列——并发集合(一)
- 如何很好的使用SVN
- Android studio下使用ShareSDK
- ListView与Adapter
- JS网址正则验证
- Jenkins中使用ant管理Android应用开发生命周期
- css之inline-block
- android opencv 环境搭建
- 兔子问题