STL下的deque,list是线程安全的吗
发布时间:2025-05-25 10:01:36 发布人:远客网络
一、STL下的deque,list是线程安全的吗
STL下的deque,list是线程安全的
java中解决这个问题通常有两种方法
二:使用Collections.synchronizedList();
假如你创建的代码如下:List<Map<String,Object>> data=new ArrayList<Map<String,Object>>();
那么为了解决这个线程安全问题你可以这么使用Collections.synchronizedList()
List<Map<String,Object>> data=Collections.synchronizedList(new ArrayList<Map<String,Object>>());
把new关键字换一下就可以了其他的都没变,使用方法可以参考api文档;
一种是你自己手动实现的list数据结构,一种就是STL给你封装好的。
如果你是自己手动实现的,那么就发源码来,我帮你看怎么优化。
那么你不能期望STL给你线程支持,因为它要的是效率。
1.多个线程的读是安全的。多线程可同时读取一个容器内容。只能是读,不能写。
2.对不同容器的多个写入是安全的。多线程可以同时写不同容器。注意,是不同容器。
所以你应该自己写一个针对容器的模板类来实现加锁(构造的时候加锁,析构的时候释放),然后在访问容器的时候,定义一个该类的临时变量,临时变量可以保证如果抛出了异常,该临时对象也会被销毁,从而也释放掉锁。
二、Java ArrayDeque从头部添加
1、为了提升效率,ArrayDeque采用了循环数组设计,通过这一设计,它能够在逻辑上没有固定开头或结尾的数组中直接向头部或尾部添加数据,无需大范围移动数据。此特性使其成为高效的数据结构。
2、ArrayDeque的`addFirst()`方法代码如下:
3、 if(e== null) throw new NullPointerException();
4、 elements[head=(head- 1)&(elements.length- 1)]= e;
5、 if(head== tail) doubleCapacity();
6、在添加头部元素时,主要关注头位置的计算。新头位置始终为`head- 1`。若此结果为-1,即代表移动到数组尾部,即物理数组的最后一个位置`length- 1`。这里通过位与运算巧妙地实现这一逻辑:
7、elements[head=(head- 1)&(elements.length- 1)]= e;
8、当`head- 1`为-1时,计算`11111111& 00001111`,结果为`00001111`,即物理数组的尾部15。当`head- 1`为较小值如3时,计算`00000011& 00001111`,结果仍为`00000011`,即3。当`head`增长至超过物理数组长度时,例如16,计算`00010000& 00001111`,结果为`00000000`,即0,表示回到了物理数组头部。位与运算因而能轻松控制数据在数组内的范围。
9、`addFirst()`方法首先将`head`指向前一个位置,再将元素赋值给`head`所在位置。例如,初始`head`为0,若`elements.length`为8,则`(head- 1)&(elements.length- 1)`的结果为7。执行以下代码:
10、Deque queue= new ArrayDeque<>(7);
11、执行后,`ArrayDeque`内部结构如图所示,形象地展示了向头部添加元素的过程。
三、queue和column
1、Queue:基本上,一个队列就是一个先入先出(FIFO)的数据结构,Queue接口与List、Set同一级别,都是继承了Collection接口。LinkedList实现了Deque接口。Queue的实现,没有实现的阻塞接口的LinkedList:实现了java.util.Queue接口和java.util.AbstractQueue接口,内置的不阻塞队列: PriorityQueue和 ConcurrentLinkedQueue,PriorityQueue和 ConcurrentLinkedQueue类在 Collection Framework中加入两个具体集合实现。PriorityQueue类实质上维护了一个有序列表。加入到 Queue中的元素根据它们的天然排序(通过其 java.util.Comparable实现)或者根据传递给构造函数的 java.util.Comparator实现来定位。ConcurrentLinkedQueue是基于链接节点的、线程安全的队列。并发访问不需要同步。因为它在队列的尾部添加元素并从头部删除它们,所以只要不需要知道队列的大小,ConcurrentLinkedQueue对公共集合的共享访问就可以工作得很好。收集关于队列大小的信息会很慢,需要遍历队列。
2、如果省略参数 reference或该参数为一个单元格区域,并且 COLUMN函数是以水平数组公式的形式输入的,则 COLUMN函数将以水平数组的形式返回参数 reference的列号。如果参数 reference为一个单元格区域,并且 COLUMN函数不是以水平数组公式的形式输入的,则 COLUMN函数将返回最左侧列的列号。如果省略参数 reference,则假定该参数为对 COLUMN函数所在单元格的引用。参数 reference不能引用多个区域。