java容器及其并发容器的演进
static List<String> arrayList = new ArrayList();
static {
for (int i = 0; i < 10000; i++) {
arrayList.add("编号:" + i);
}
}
//会出现多线线程处理同一个元素
for (int i = 0; i < 10; i++) {
new Thread(() -> {
while (arrayList.size() > 0) {
System.out.println("售票--" + arrayList.remove(0));
}
}).start();
}
static Vector<String> vector = new Vector<>();
static {
for (int i = 0; i < 10000; i++) {
vector.add("编号:" + i);
}
}
//线程安全的容器
//在判断vector.size() 与remove移除之间没有枷锁 还是会出现超卖现象
for (int i = 0; i < 10; i++) {
new Thread(() -> {
while (vector.size() > 0) {
try {
TimeUnit.MILLISECONDS.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("售票--" + vector.remove(0));
}
}).start();
}
static LinkedList<String> linkList = new LinkedList<>();
static {
for (int i = 0; i < 1000; i++) {
linkList.add("编号:" + i);
}
}
//线程安全的容器 枷锁
// 给整个容器加上锁 每个线程都获取对象linkList锁 但是效率比较低
for (int i = 0; i < 10; i++) {
new Thread(() -> {
while (true) {
synchronized (linkList) {
if (linkList.size() <=0) break;
try {
TimeUnit.MILLISECONDS.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("售票--" + linkList.remove(0));
}
}
}).start();
}
static Queue<String> queue = new ConcurrentLinkedDeque<>();
static {
for (int i = 0; i < 10000; i++) {
queue.add("编号:" + i);
}
}
//多线程访问单个元素 并发性能较好的方式
for (int i = 0; i < 10; i++) {
new Thread(() -> {
while (true) {
String poll = queue.poll();
if (poll == null) break;
else System.out.println("售票--" + poll);
}
}).start();
}
思考:LinkedList与ConcurrentLinkedDeque有何区别?
/**
* LinkedList的内部数据结构
* 基于链表实现:LinkedList是一个双向链表,每个节点包含三个部分:元素本身、指向前一个节点的引用(prev)和指向后一个节点的引用(next)。这种结构使得在链表中间插入和删除元素相对高效,因为只需要修改相关节点之间的引用关系。
* 非线程安全的结构设计:它没有内置的并发控制机制。在多线程环境下,如果多个线程同时访问和修改LinkedList,比如一个线程在遍历链表,另一个线程在删除某个节点,就可能导致数据不一致或者抛出ConcurrentModificationException。
* ConcurrentLinkedDeque的内部数据结构
* 也是基于链表实现的双端队列:ConcurrentLinkedDeque同样是一个链表结构,并且是双向的。每个节点也有元素本身、指向前一个节点的引用和指向后一个节点的引用。不过,它采用了更加复杂的算法来实现无锁并发访问。
* 使用无锁算法和 CAS 操作:它利用了 CAS 操作来实现并发安全。在插入和删除元素时,通过原子性的比较和交换操作来更新节点的引用。例如,当插入一个新元素时,会尝试以原子方式更新相关节点的引用,以确保数据的一致性和并发安全性。这种设计使得多个线程可以同时对队列进行操作,而不会像传统的加锁机制那样造成阻塞。
* 节点标记和辅助机制用于并发控制:ConcurrentLinkedDeque还采用了一些特殊的节点标记和辅助手段来帮助管理并发操作。例如,节点可能会有一些标记来指示其状态(如是否已经被逻辑删除等),这些标记在并发操作过程中发挥着重要作用,以保证在高并发环境下队列的正常运行。
*/
本文来自博客园,作者:余生请多指教ANT,转载请注明原文链接:https://www.cnblogs.com/wangbiaohistory/p/18640293

浙公网安备 33010602011771号