热门标签 | 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);
}


推荐阅读
  • 我有3个来自RESEARCHS的映射值,指定要使用参考数据集填充的行中的范围。该研究 ... [详细]
  • 本文节选自《NLTK基础教程——用NLTK和Python库构建机器学习应用》一书的第1章第1.2节,作者Nitin Hardeniya。本文将带领读者快速了解Python的基础知识,为后续的机器学习应用打下坚实的基础。 ... [详细]
  • 检查在所有可能的“?”替换中,给定的二进制字符串中是否出现子字符串“10”带 1 或 0 ... [详细]
  • 本文介绍了如何在iOS平台上使用GLSL着色器将YV12格式的视频帧数据转换为RGB格式,并展示了转换后的图像效果。通过详细的技术实现步骤和代码示例,读者可以轻松掌握这一过程,适用于需要进行视频处理的应用开发。 ... [详细]
  • HashMap:键值对(key-value):通过对象来对对象进行索引,用来索引的对象叫做key,其对应的对象叫做value.默认是1:1关系:存在则覆盖,当key已经存在,则利用新的va ... [详细]
  • 缓存这个东西就是为了提高运行速度的,由于缓存是在寸土寸金的内存里面,不是在硬盘里面,所以容量是很有限的。LRU这个算法就是把最近一次使用时间离现在时间最远的数据删除掉。先说说List:每 ... [详细]
  • MySQL初级篇——字符串、日期时间、流程控制函数的相关应用
    文章目录:1.字符串函数2.日期时间函数2.1获取日期时间2.2日期与时间戳的转换2.3获取年月日、时分秒、星期数、天数等函数2.4时间和秒钟的转换2. ... [详细]
  • 零拷贝技术是提高I/O性能的重要手段,常用于Java NIO、Netty、Kafka等框架中。本文将详细解析零拷贝技术的原理及其应用。 ... [详细]
  • 本教程详细介绍了如何使用 Spring Boot 创建一个简单的 Hello World 应用程序。适合初学者快速上手。 ... [详细]
  • 本文是Java并发编程系列的开篇之作,将详细解析Java 1.5及以上版本中提供的并发工具。文章假设读者已经具备同步和易失性关键字的基本知识,重点介绍信号量机制的内部工作原理及其在实际开发中的应用。 ... [详细]
  • 属性类 `Properties` 是 `Hashtable` 类的子类,用于存储键值对形式的数据。该类在 Java 中广泛应用于配置文件的读取与写入,支持字符串类型的键和值。通过 `Properties` 类,开发者可以方便地进行配置信息的管理,确保应用程序的灵活性和可维护性。此外,`Properties` 类还提供了加载和保存属性文件的方法,使其在实际开发中具有较高的实用价值。 ... [详细]
  • 本文详细介绍了 Java 中遍历 Map 对象的几种常见方法及其应用场景。首先,通过 `entrySet` 方法结合增强型 for 循环进行遍历是最常用的方式,适用于需要同时访问键和值的场景。此外,还探讨了使用 `keySet` 和 `values` 方法分别遍历键和值的技巧,以及使用迭代器(Iterator)进行更灵活的遍历操作。每种方法都附有示例代码和具体的应用实例,帮助开发者更好地理解和选择合适的遍历策略。 ... [详细]
  • 本文总结了JavaScript的核心知识点和实用技巧,涵盖了变量声明、DOM操作、事件处理等重要方面。例如,通过`event.srcElement`获取触发事件的元素,并使用`alert`显示其HTML结构;利用`innerText`和`innerHTML`属性分别设置和获取文本内容及HTML内容。此外,还介绍了如何在表单中动态生成和操作``元素,以便更好地处理用户输入。这些技巧对于提升前端开发效率和代码质量具有重要意义。 ... [详细]
  • HashTable与ConcurrentHashMap均可实现HashMap的功能,对外提供了键值对存储的数据结构。但是在内部结构及实现上有何区别,性能上的差异到底在哪里又是如何导致的 ... [详细]
  • 我有一个从C项目编译的.o文件,该文件引用了名为init_static_pool ... [详细]
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社区 版权所有