热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

JAVA8并发增强(3)ConcurrentHashMap改进

***ConcurrentHashMap是线性安全的,多个线程不需要对内部结构造成破坏,就可以删除或者添加元素。*性能高,允许多个线程并发更新哈希表的不停部分,而不会造成相互堵塞*
/**
* ConcurrentHashMap是线性安全的,多个线程不需要对内部结构造成破坏,就可以删除或者添加元素。
* 性能高,允许多个线程并发更新哈希表的不停部分,而不会造成相互堵塞
* ConcurrentHashMap的size是int类型,J8为了应付数量巨大的并发哈希映射,引入了一个mappingCount方法
* 用来返回一个反应大小的long型值 tips:哈希映射将会将具有相同哈希码的所有数据保存在同一个“块”中。某些应用程序使用了糟糕的哈希函数,
* 导致所有数据项都被保存在了很小的一组块中,这严重影响了哈希映射的效率。即使是一般认为合理的哈希函数,
* 例如String类的hashCode方法,也可能会存在问题。例如,攻击者可以通过构造一组大量的哈希码都一样的字符串来拉低程序的速度。
* 在java8中,并发哈希映射用树形结构来组织“块”,而不再用散列表的结构,这样当键类实现了Comparable接口时, 可以保证性能为a(log(n))
* tips:看起来一个本应线程安全的数据结构竟然允许线程不安全的操作。但是这是出于两种不同的考虑。
* 如果多个线程修改一个普通的HashMap,他们可能会破坏内部结构(一个链表数组)。其中一些链接可能会丢失,或者形成了回路
* 从而导致数据结构不可用。在conccurentHashMap中这永远不会发生。get和put代码永远不会破坏数据结构。
* 但是由于操作顺序不是原子的,因此结果也无法预测。
*/
public class ConcurrentHashMapTest {

public static void main(String[] args) {
ConcurrentHashMap map = new ConcurrentHashMap<>();
// ①错误的方式
String word = "key";
Long oldValue = map.get(word);
Long newValue = oldValue == null ? 1 : oldValue + 1;
map.put(word, newValue);
// ②一种补救措施是使用replace操作,将一个已知的旧值替换为一个新值。
do {
oldValue = map.get(word);
newValue = oldValue == null ? 1 : oldValue + 1;
} while (!map.replace(word, oldValue, newValue));

/** 改进方法1 */
Map map2 = new ConcurrentHashMap();
/** 改进方法2,仅限于java8以上 */
Map map3 = new ConcurrentHashMap();
map3.put(word, new LongAdder());
/** 改进方法2.1,将两条语句合为一条 */
map3.putIfAbsent(word, new LongAdder()).increment();
/**
* j8提供了很多可以更方便进行原子更新的方法。compute可以通过一个键和一个函数来计算出新的值
* 该函数会获取键及其所关联的值(如果没有值则为null),然后计算出新的值 下面是更新一个整型计数器的映射
*/
map.compute(word, (k, v) -> v == null ? 1 : v + 1);
/**
* 此外,ConcurrentHashMap还提供了computeIfPresent和computeIfAbsent方法,
* 分别在已经存在值和尚未存在值的情况下,才计算新值。因此LongAdder计算器的映射可以更新为如下代码:
* 这与之间的putIfAbsent的方法非常相似,但是LongAdder构造函数只有在需要一个 新计数器时才会调用
*/
map3.computeIfAbsent(word, k -> new LongAdder()).increment();
/**
* 通常,当一个键第一次被加入到映射时,你需要做一些特殊的事情,那么使用merge方法会非常方便
* 它的一个参数用来表示键尚未存在时的初始值。相反,只有在已有值和初始值相结合的时候,你提供的函数才会被调用
* (不像compute方法,该函数不会处理键)
*/
map.merge(word, 1L, (existingVal, newVal) -> existingVal + newVal);
/**
* 或者这样
* tips:①如果传递给compute或者merge方法的函数返回null,那么已有的数据项会从映射表中抹掉
* ②当你使用compute或者merge方法时,请牢记你所提供的函数不应该进行大量工作。
* 当函数运行时,其他一些更新映射的操作可能会被阻塞,当然该函数也不应该更新映射的其他部分
*/
map.merge(word, 1L, Long::sum);
}


推荐阅读
  • 01Map集合概述A:Map集合概述:我们通过查看Map接口描述,发现Map接口下的集合与Collection接口下的集合,它们存储数据的形式不同a:Collection中的集合 ... [详细]
  • HashTable与ConcurrentHashMap均可实现HashMap的功能,对外提供了键值对存储的数据结构。但是在内部结构及实现上有何区别,性能上的差异到底在哪里又是如何导致的 ... [详细]
  • 缓存这个东西就是为了提高运行速度的,由于缓存是在寸土寸金的内存里面,不是在硬盘里面,所以容量是很有限的。LRU这个算法就是把最近一次使用时间离现在时间最远的数据删除掉。先说说List:每 ... [详细]
  • 本篇文章给大家分享的是有关Java中怎么对HashMap按键值排序,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话 ... [详细]
  • HashMap的相关问题及其底层数据结构和操作流程
    本文介绍了关于HashMap的相关问题,包括其底层数据结构、JDK1.7和JDK1.8的差异、红黑树的使用、扩容和树化的条件、退化为链表的情况、索引的计算方法、hashcode和hash()方法的作用、数组容量的选择、Put方法的流程以及并发问题下的操作。文章还提到了扩容死链和数据错乱的问题,并探讨了key的设计要求。对于对Java面试中的HashMap问题感兴趣的读者,本文将为您提供一些有用的技术和经验。 ... [详细]
  • HashMap:键值对(key-value):通过对象来对对象进行索引,用来索引的对象叫做key,其对应的对象叫做value.默认是1:1关系:存在则覆盖,当key已经存在,则利用新的va ... [详细]
  • 类Hashtable<K,V>所有已实现的接口:Serializable,Cloneable,Map<K,V>此类实现一个哈希表,该哈希表将键映 ... [详细]
  • 将学生对象和学生的归属地通过键与值存储到map集合中。importjava.util.HashMap;importjava.util.Iterator;importjava.uti ... [详细]
  • 手写HashMap,快手面试官直呼内行
    手写HashMap,快手面试官直呼内行-手写HashMap?这么狠,面试都卷到这种程度了?第一次见到这个面试题,是在某个不方便透露姓名的Offer收割机大佬的文章:这……我当 ... [详细]
  • 本文介绍了Redis的基础数据结构string的应用场景,并以面试的形式进行问答讲解,帮助读者更好地理解和应用Redis。同时,描述了一位面试者的心理状态和面试官的行为。 ... [详细]
  • 本文介绍了如何在给定的有序字符序列中插入新字符,并保持序列的有序性。通过示例代码演示了插入过程,以及插入后的字符序列。 ... [详细]
  • 本文由编程笔记#小编为大家整理,主要介绍了源码分析--ConcurrentHashMap与HashTable(JDK1.8)相关的知识,希望对你有一定的参考价值。  Concu ... [详细]
  • 单线程化的ConcurrentHashMap的性能要比同步的HashMap的性能稍好一些,而且在并发应用中,这种作用就十分明显了。ConcurrentHashMap的实现,假定大多数常用的操 ... [详细]
  • 我有3个来自RESEARCHS的映射值,指定要使用参考数据集填充的行中的范围。该研究 ... [详细]
  • Java之HashMap在多线程情况下导致死循环的问题
    PS:不得不说Java编程思想这本书是真心强大..学习内容:1.HashMap<K,V>在多线程的情况下出现的死循环现象当初学Java的时候只是知道HashMap< ... [详细]
author-avatar
lnssm
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有