我要投搞

标签云

收藏小站

爱尚经典语录、名言、句子、散文、日志、唯美图片

当前位置:港彩神鹰 > 读入原语 >

【多线程高并发】 同步容器和队列

归档日期:05-05       文本归类:读入原语      文章编辑:爱尚语录

  同步容器都是线程安全的,但是在某些场景下可能需要加锁来保护复合操作,复合类操作如 迭代,跳转,条件运算等,这些复合操作在多线程并发执行的时候。可能会出现意外行为,最经典的便是ConcurrentModificationException,原因是当容器迭代的过程中,被并发的修改了内容。

  同步类容器: 如古老的Vector,HashTable。这些容器的同步功能其实都是由JDK的Collections.synchronized等工厂方法去实现的,其底层的机制无非就是用传统的synchronized关键字对每个公用的方法都进行同步,使得每次只能有一个线程访问容器的状态。这很明显不符合今天互联网时代高并发的需求,在保证线程安全的同时,也必须要有足够好的性能。

  ConcurrentHashMap主要是利用了Segment(段)的方式,来减小锁的粒度,从而实现提高并发性能的机制, 最大可以分成16段。并且代码中大多共享变量使用Volatile关键字声明,目的是第一时间获取修改的内容,性能非常好

  如图,传统的HashTable,只有一段,对整个map进行加锁,锁的粒度比较大。而CorrentHashMap, 对这个map的某一个小Segment来进行加锁,在哪一段操作,只锁定哪一个段,其他段不影响,锁的粒度比较小,从而提高并发的性能

  具体如何使用,和之前的HashMap几乎是一模一样的,还是随便看个例子吧

  Copy-On-Write简称COW, 是一种用于程序设计中的优化策略。

  Copy容器即写时复制的容器,先将当前容器进行Copy,复制出一个新的容器,然后想信的容器里面添加元素,添加完后,在讲原容器的引用指向新的容器。这样的好处是我们可以对CopyOnWrite容器进行并发的读而不用加锁,因为当前容器不会添加任何元素,所以CopyOnWrite也是一种读写分离的思想,读和写不同的容器,适用于读多写少的场景。

  在并发队列上JDK提供了两套实现,一个是以ConcurrentLinkedQueue为代表的高性能队列,一个是以BlockingQueue接口为代表的阻塞队列,无论哪种都继承自Queue

  ConcurrentLinkedQueue: 是一个适用于高并发场景下的队列,通过无锁的方式,实现了高并发状态下的高性能,通常ConcurrentLinkedQueue性能好于BlockingQueue,他是一个基于链接节点的无界线程安全队列,该队列的元素遵循先进先出的原则,头是最新加入,尾是最近加入。该队列不允许null元素。

  poll()和peek()都是取头元素节点,区别在于前者会删除元素,后者不会。

  基于数组的阻塞队列实现,在ArrayBlockingQueue内部,维护了一个定常数组,一边缓存队列中的数据对象,其内部没有实现读写分离,也就意味着生产和消费不能完全并行,长度是需要定义的,可以指定先进先出或者先进后出。也叫有界队列,在很多场合下非常适用。

  由于指定的是5个长度,前面已经加了5个了,后面再次添加的时候,3秒内都加不进去,3秒后返回一个false,输出

  基于链表的阻塞队列,同ArrayBlockingQueue类似,其内部也维护者一个数据缓冲队列(该队列是由一个链表构成),LinkBlockingQueue之所以能够搞笑的处理并发数据,是因为其内部实现了读写分离锁,从而实现了生产者和消费者的完全并行运行,他是一个无界队列。

  基于优先级的阻塞队列(优先级的判断通过构造函数传入的Compator对象来决定,也就是说传入队列的对象必须实现Comparable接口),在实现PriorityBlockingQueue时,内部控制线程同步的锁采用的是公平锁,他也是一个无界的队列。

  说明,这种队列在没有take的时候,还不是排序的,take()时,才利用了排序,比较的方法

  带有延迟时间的Queue, 其中的元素只有当其指定的延迟时间到了,才能够从队列中获取到该元素,DelayQueue的元素必须实现Delayed 接口, DelayQueue是一个没有大小限制的队列,应用场景很多,比如对缓存超时的数据进行一处,任务超时处理,空闲连接的关闭等等。

  最近再做一个高并发的服务器处理程序,服务器要用多线程处理大数据量计算,然后将计算结果封装成消息放入队列中,然后另起几个线程专门负责处理消息队列中的消息分发给不同客户端,这样瓶颈就出来了,N多线程都在频...博文来自:明潮的BLOG

  C++程序,两个线程同时访问一个容器,读的时候同时会往里写,如果枷锁,那么读的时候,就不能写,数据机会丢。如果不加锁,可能会有两个线程同时操作一块内存会有问题。以前试过用列表复制的方式,但是数据很大速论坛

  最近看到一本书,《C++并发编程实战》,[美]AnthonyWilliams著,里面有谈及线程安全容器的设计及实现代码,本人觉得这样的设计有点问题,问题还是比较明显的,写在这里,供读者自己思考吧。  ...博文来自:weixin_36597302的博客

  这里主要是简单介绍几种比较常见的并发容器,目的是梳理一下。由于每一个类的底层实现都是非常复杂的,用到了很多精妙的多线程的技巧,限于篇幅和水平,就不做深入的探讨。纸上得来终觉浅,只有多加实践,多看源码,...博文来自:Allen的专栏

  遇到问题:最近做微信支付,项目上线一阵,发现一个问题。有一条订单流水居然在数据库的出现两次。这个问题非常严重。查看微信回调系统的接口代码发现代码是没错的(正常情况下),而这次遇到非正常情况了原因:微信...博文来自:white__cat的专栏

  CopyOnWrite容器如同它的名字一样,在操作容器时候,如果涉及写操作则复制一份拷贝,操作这份拷贝。下面我们以CopyOnWriteArrayList为例子进行说明。...博文来自:成长之路

  (一)SparkContext代表对集群的一个连接(二)Job提交过程底层分析,包括DAGScheduler,taskScheduler的分析(三)、Spark提交Job的顺序的小实验...博文来自:可可的专栏

  std::thread类1.1,什么叫并发concurrency?一遍走路一边说话;你打球我游泳单核计算机上的并发是个假象,其实只是任务切换(taskswitching)需要上下文切换多处理器或一个处...博文

  在并发队列上JDK提供了两套实现,一个是以ConcurrentLinkedQueue为代表的高性能队列,一个是以BlockingQueue接口为代表的阻塞队列,无论哪种都继承自Queue。Concur...博文

  对于我们开发的网站,如果网站的访问量非常大的话,那么我们就需要考虑相关的并发访问问题了。而并发问题是绝大部分的程序员头疼的问题,但话又说回来了,既然逃避不掉,那我们就坦然面对吧~今天就让我们一起来研究...博文

  在多线队列简介队列是一种特殊的线性表,特殊之处在于它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作,和栈一样,队列是一种操作受限制的线性表。进行插入操作的端...博文来自:木兰坠露的专栏

  在Java多线程应用中,队列的使用率很高,多数生产消费模型的首选数据结构就是队列。Java提供的线程安全的Queue可以分为阻塞队列和非阻塞队列,其中阻塞队列的典型例子是BlockingQueue,非...博文来自:

  以前在项目中很少用到队列,其实队列对于解决并发很是重要,今天着手看了相关资料并实际简单操作,如下:1.队列的含义:队列就是一种特殊的线性表,采用FIFO方式,而栈是LIFO方式。2.常用的队列:Lin...博文来自:

  同步容器类同步容器类包括Vector和Hashtable(二者是早期JDK的一部分),还包括JDK1.2中添加的一些相似的类。同步容器类实现线程安全的方式是:将状态封闭起来,并对每个公有方法进行同步,...博文来自:huilangeliuxin的专栏

  10-12阅读数 7361在并发编程中,会经常遇到使用容器。但是如果一个容器不是线程安全的,那么他在多线程的插入或者删除的过程中就会出现各种问题,就是不同步的问题。所以JDK提供了线程安全的容器,他能保证容器在多线程的情况下安...

  CopyOnWrite从字面上理解就是写入的时候做复制操作。而CopyOnWrite是一个Java5之后出现的并发容器,目的是为了提高并发的存取效率。对比CopyOnWrite、ArrayList和V...博文来自:Martin的专栏

  Copy-On-Write简称COW,是一种用于程序设计中的优化策略。其基本思路是,从一开始大家都在共享同一个内容,当某个人想要修改这个内容的时候,才会真正把内容Copy出去形成一个新的内容然后再改,...

  使用的是全志H3的芯片,运行Debian Desktop系统的ARM版本Armbian,要控制外部几个IO口,可以使用很多种方法,如果对GPIO的操作速度有要求就需要使用直接操作内存寄存器的方式来控制...博文来自:

本文链接:http://chuyenchame.com/duruyuanyu/243.html