首页 > 编程语言 >java容器及其并发容器的演进

java容器及其并发容器的演进

时间:2024-12-30 10:32:10浏览次数:1  
标签:容器 java ++ 并发 static new 线程 节点

   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还采用了一些特殊的节点标记和辅助手段来帮助管理并发操作。例如,节点可能会有一些标记来指示其状态(如是否已经被逻辑删除等),这些标记在并发操作过程中发挥着重要作用,以保证在高并发环境下队列的正常运行。
         */

  

标签:容器,java,++,并发,static,new,线程,节点
From: https://www.cnblogs.com/wangbiaohistory/p/18640293

相关文章

  • java.sql.SQLException: CLI-specific condition, message from server: "Host '10.1
    您遇到的错误信息表明,MySQL服务器由于检测到来自主机'10.11.xxx.xx'的多次连接错误而自动封锁了该主机的连接请求。这是一种数据库安全机制,旨在防止潜在的恶意攻击或配置不当导致的资源滥用。要解决这个问题,您可以采取以下步骤:检查网络连接:确保客户端和服务器之间的网络稳定,并......
  • Android 兼容 Java 8 语法特性的原理分析4
       本文主要阐述了Lambda表达式及其底层实现(invokedynamic指令)的原理、Android第三方插件RetroLambda对其的支持过程、Android官方最新的dex编译器D8对其的编译支持。通过对这三个方面的跟踪分析,以Java8的代表性特性——Lambda表达式为着眼点,将Android如何兼容Java8的过程......
  • 两个定时任务的并发问题,导致数据处理的顺序和状态变得混乱
    1.背景:有两个定时任务在特定时间触发,同时对数据进行操作,且任务之间存在并发执行的场景。主要涉及的表为lingyejun_task,涉及到的操作有:数据插入、推送、状态更新和错误处理。定时任务A负责生成数据,定时任务B负责将生成好的数据处理并推送到第三方系统,由于出问题的时候定时任务A......
  • java期末总结第二章
    2.java编程基础1.标识符与命名规范标识符是给Java中的类、方法、变量、包命名的符号:只能由字母、数字、下划线、美元符号组成,并且不能以数字开头。Java标识符大小写敏感,长度无限制标识符不可以是Java关键字和保留字2.变量的定义和赋值变量赋值语法如下:inta,b,c;//声......
  • Java多线程实战避坑指南:从入门到生产实践
    在微服务架构下,多线程编程已经成为Java开发者的必备技能。本文将帮助你掌握多线程开发的核心知识,避开常见陷阱。一、为什么要深入理解多线程?1.1现实问题接口响应慢CPU利用率低内存泄漏频发死锁难以排查并发BUG难复现1.2业务场景批量数据处理并行任务执行......
  • 【html】通用布局模式,让容器充满父元素,且center部分始终充满剩余空间,可无限嵌套
    源码采用vue3写法实现:Panel.vue<!--专用于布局的面板,可以无限嵌套,核心思想是保证center部分充满整个剩余空间--><template> <divclass="container"> <divclass="top"> <slotname="top"/> </div> <divclass="middle&q......
  • LeetCode热题100-移动零【JavaScript讲解】
    题目:快指针和慢指针同时移动,当遍历的值不为0的时候,将快指针的值赋给慢指针,如果遍历到0,快指针继续移动,慢指针不动等待被覆盖。之后使用fill方法填充0。具体答案放在最后啦~fill方法arr.fill(value[,start[,end]])参数说明:value:用于填充数组元素的值start(可选):开始......
  • Java 大视界 -- Java 大数据测试框架与实践:确保数据处理质量(十二)
           ......
  • Java学习教程,从入门到精通,Java I/O流语法知识点及案例代码(70)
    JavaI/O流语法知识点及案例代码一、JavaI/O流语法知识点I/O流简介I/O(Input/Output)流是Java中用于处理输入和输出数据的机制。允许程序与外部设备(如文件、网络连接、内存等)进行数据交换。I/O流的分类字节流(ByteStreams):以字节为单位进行操作,适用于处理二进制数据或......
  • 每日算法----链表相交(Java)
    双指针需要找到相交节点,特殊情况两个链表在相交前的节点个数是相同的,这种情况我们只需用两个指针同时遍历两个链表,当currA==currB时,此时就找到了相交节点。从这个特殊情况可以看出来,我们需要两个链表在相交前的节点个数是相同的,对于两个相交节点不同的情况,当链表A遍历完后,我......