当前位置: 首页 > wzjs >正文

道滘网站建设哈尔滨网络优化推广公司

道滘网站建设,哈尔滨网络优化推广公司,建网站免费吗,wordpress删主题目录:多线程环境下使用ArrayList多线程环境下使用队列多线程环境下使用哈希表多线程环境下使用ArrayList在多线程环境下使用ArrayList可以有以下三种方式:1.使用同步机制 (synchronized 或者 ReentrantLock)2.Collections.synchronizedList(new ArrayLis…

目录:

多线程环境下使用ArrayList

多线程环境下使用队列

多线程环境下使用哈希表


多线程环境下使用ArrayList

在多线程环境下使用ArrayList可以有以下三种方式:

1.使用同步机制 (synchronized 或者 ReentrantLock)

2.Collections.synchronizedList(new ArrayList),synchronizedList 是标准库提供的一个基于synchronized 进行线程同步的 List,synchronizedList 的关键操作上都带有 synchronized,使用这个方法把集合类套一层。

3.使用 CopyOnWriteArrayList

CopyOnWrite容器即写时复制的容器,简称“COW”,也叫做“写时拷贝”。如果针对这个ArrayList进行读操作,不做任何额外的工作。如果进行写操作,则拷贝一份新的ArrayList,针对新的进行修改,修改过程中如果有读操作,就继续读旧的这份数据。当修改完毕了,使用新的替换旧的(本质上就是一个引用之间的赋值,是原子的)。

很明显,这种方案,优点是不需要加锁,不需要锁竞争,在读多写少的场景下的性能很高;缺点则是要求这个ArrayList不能太大,否则占用内存太大,而且新写的数据不能第一时间被读到。

多线程环境下使用队列

1) ArrayBlockingQueue 基于数组实现的阻塞队列

2) LinkedBlockingQueue 基于链表实现的阻塞队列

3) PriorityBlockingQueue 基于堆实现的带优先级的阻塞队列

4) TransferQueue 最多只包含一个元素的阻塞队列

TransferQueue 的应用场景是,当不想生产者过度生产消息时,TransferQueue可能非常有用,在这样的设计中,消费者的消费能力将决定生产者产生消息的速度。

多线程环境下使用哈希表

HashMap 本身不是线程安全的,在多线程环境下使用哈希表可以使用:Hashtable和ConcurrentHashMap

Hashtable是线程安全的,它是在关键方法上加了synchronized。更推荐使用的是ConcurrentHashMap,它是更优化的线程安全哈希表。

ConcurrentHashMap进行了哪些优化?比HashTable好在哪里?和HashTable之间的区别是啥?

1.最大的优化之处:ConcurrentHashMap相比于HashTable 大大缩小了锁冲突的概率,把一把大锁,转换成多把小锁了。

HashTable的做法是直接在方法上加synchronized,等于是给this加锁,只要操作哈希表上的任意元素,都会产生加锁,也就都可能会发生锁冲突。但是实际上,基于哈希表的结构特点,有些元素在进行并发操作的时候,是不会产生线程安全问题的,也就不需要使用锁控制。

此时元素1和元素2在同一链表上,如果线程A修改(增删)元素1,线程B修改元素2,那么此时是有线程安全问题的(相邻两元素并发的插入或者删除的时候,相邻两节点的next指向可能会发生改变)。如果线程A修改(增或者删)元素3,线程B修改元素4,,这个情况相当于多个线程修改不同的变量,那么此时是没有线程安全问题的。

使用HashTable,锁冲突概率就太大了,任何两个元素的操作都会有锁冲突,即使是处在不同的链表上,这就是不用HashTable的主要原因。

ConcurrentHashMap做法是,每个链表有各自的锁(而不是大家共用同一个锁了),具体来说,就是使用每个链表的头结点,作为锁对象(两个线程针对同一个锁对象加锁才有锁竞争,才有阻塞等待,针对不同对象,没有锁竞争)。

此时,把锁的粒度变小了,针对12这个情况,是针对同一把锁进行加锁,会有锁竞争,会保证线程安全。针对34这个情况,是针对不同的锁进行加锁,不会有锁竞争了,没有阻塞等待,程序就会更快。

2.针对读操作,不加锁,只针对写操作加锁

读和读之间没有冲突;写和写之间有冲突,可以加锁;读和写之间没有冲突,但是很多场景下,读写之间不加锁控制,如果写操作不是原子的,那么会产生脏读,所以使用了 volatile 保证了原子性。

3.ConcurrentHashMap内部充分的使用了CAS,通过这个也来进一步的削减加锁操作的数目

4.针对扩容,采取了"化整为零"的方式

HashMap/HashTable扩容:

创建一个更大的数组空间,把旧的数组上的链表上的每个元素搬运到新的数组上(删除+插入),这个扩容操作会在某次put 的时候进行触发。如果元素个数特别多,就会导致这样的搬运操作,比较耗时。

ConcurrentHashMap 中,扩容采取的是每次搬运一小部分元素的方式。创建新的数组,旧的数组也保留。每次 put 操作,都往新数组上添加,同时进行一部分搬运(把一小部分旧的元素搬运到新数组上)。每次get的时候,则旧数组和新数组都查询。每次remove 的时候,只是把元素删了就行了。经过一定时间之后,所有的元素都搬运好了,最终再释放旧数组。

小结:

Hashtable和HashMap、ConcurrentHashMap 之间的区别?

HashMap: 线程不安全. key 允许为 null

Hashtable: 线程安全,使用 synchronized 锁 Hashtable 对象, 效率较低,key 不允许为 null

ConcurrentHashMap: 线程安全,使用 synchronized 锁每个链表头结点, 锁冲突概率低, 充分利用

CAS 机制,优化了扩容方式,key 不允许为 null

ConcurrentHashMap在jdk1.8做了哪些优化?

取消了分段锁, 直接给每个哈希桶(每个链表)分配了一个锁(就是以每个链表的头结点对象作为锁对象)。将原来 数组 + 链表 的实现方式改进成 数组 + 链表 / 红黑树 的方式,当链表较长的时候(大于等于

8 个元素)就转换成红黑树。

PS:分段锁是 Java1.7 中采取的技术,Java1.8 中已经不再使用了,简单的说就是把若干个哈希桶分成一个

"段", 针对每个段分别加锁,目的也是为了降低锁竞争的概率。当两个线程访问的数据恰好在同一个段上的时候, 才触发锁竞争。

ConcurrentHashMap的读是否要加锁?

读操作没有加锁,目的是为了进一步降低锁冲突的概率,为了解决脏读,保证读到刚修改的数据, 搭配了

volatile 关键字。

http://www.dtcms.com/wzjs/85846.html

相关文章:

  • 做美女图片网站合法吗东莞网络科技公司排名
  • 中国最新军事新闻最新消息视频百度搜索引擎优化指南最新版
  • 网站建设经费预算包括哪些坚决把快准严细实要求落实到位
  • 西安外贸网站建设91永久海外地域网名
  • 星月教你做网站回顾文档优化游戏性能的软件
  • 网站怎么屏蔽ip访问seo合作
  • 网站 别名培训中心
  • 做网站发现是传销昆明seo建站
  • 上海市建设工程安全质量监督总站网站百度快照怎么没有了
  • 棕色网站模板烟台seo关键词排名
  • 网站发展建设思路seo排名优化课程
  • 禅城南庄网站制作公司地址怎么弄在百度上显示
  • 宣汉网站建设广告素材
  • 营销网站设计推广app的软文案例
  • 中企动力做的 石子厂网站武汉seo网站优化排名
  • 搜索引擎营销的四种方式海外seo是什么
  • 做资料网站是自己建服务器好还是租用好广州seo全网营销
  • 哪个网站可以帮人做ppt百度指数人群画像
  • 网页前端培训seo排名如何
  • 高安网站建设关键词生成器
  • 企业建设官方网站的目的如何外贸推广
  • 网页设计和网站开发有什么区别seo长尾关键词排名
  • 天猫开店的入驻流程重庆seo网页优化
  • 山东乐陵疫情最新消息今天优化关键词具体要怎么做
  • 常州企业网站新媒体seo培训
  • wordpress使用阿里云cdn天津seo托管
  • 泉州市城乡建设委员会网站推广网页
  • 网站建设难点分析友情贴吧
  • wordpress页面菜单保定seo博客
  • 如何注册新账号东莞网站关键词优化公司