并发编程中的ConcurrentHashMap

对于ConcurrentHashMap相信大家很多的应用中都有用到,它的一些详细介绍各大博主都已经讲的详细的不能再详细了,接下来我们主要看下他的一些实现方法。

下面这个是我的应用中用到的,大家可以借鉴操作(可以做到即办即用)

目录

CSDN给的优缺点

优点:

缺点:

使用场景:

对应方法


ConcurrentHashMap是Java中并发编程中常用的一种线程安全的哈希表,它是对Hashtable的替代方案,相比于Hashtable能够更好地支持并发访问。

CSDN给的优缺点

优点:
  • 线程安全:ConcurrentHashMap中的所有方法都是线程安全的;
  • 高效性:ConcurrentHashMap使用分段锁技术,可以有效地缩小锁的范围,提高了并发访问的性能;
  • 支持高并发:ConcurrentHashMap中每个Segment都相互独立,因此可以支持更高的并发量;
缺点:
  • 内存占用:ConcurrentHashMap的分段锁机制增加了内存的占用;
  • 不支持键值为null:ConcurrentHashMap的键值不支持为null,如果需要使用null,可以使用ConcurrentSkipListMap。

使用场景:

  • 多线程并发访问:ConcurrentHashMap适用于多线程并发访问的场景;
  • 高并发量:ConcurrentHashMap适用于需要支持高并发量的场景;
  • 缓存:ConcurrentHashMap可以用于实现缓存,可以将缓存数据存储在其中。

对应方法

1、设置缓存

2、获取缓存

3、删除所有缓存

4、删除单个缓存

5、判断缓存在不在,过没过期

6、删除最近最久未使用的缓存

7、删除过期的缓存

8、检查大小

9、保存缓存的使用记录

10、设置清理线程的运行状态为正在运行

11、开启清理过期缓存的线程

import lombok.Data;import java.io.Serializable;/*** 缓存*/
@Data
public class CacheObj implements Serializable {private static final long serialVersionUID = 5272376851165037333L;/*** 缓存对象*/private Object cacheValue;/*** 缓存过期时间*/private Long ttlTime;public CacheObj(Object cacheValue, Long ttlTime) {this.cacheValue = cacheValue;this.ttlTime = ttlTime;}@Overridepublic String toString() {return "CacheObj {" +"cacheValue = " + cacheValue +", ttlTime = " + ttlTime +'}';}
}

import lombok.extern.slf4j.Slf4j;/*** 每一分钟清理一次过期缓存*/
@Slf4j
public class CleanTimeOutThread implements Runnable {@Overridepublic void run() {ConcurrentHashMapCacheUtil.setCleanThreadRun();while (true) {log.warn("clean thread run ");ConcurrentHashMapCacheUtil.deleteTimeOut();try {Thread.sleep(ConcurrentHashMapCacheUtil.ONE_MINUTE);} catch (InterruptedException e) {e.printStackTrace();}}}
}
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;/*** 本地缓存*/
@Slf4j
@Component
public class ConcurrentHashMapCacheUtil {/*** 缓存最大个数*/private static final Integer CACHE_MAX_NUMBER = 50000;/*** 当前缓存个数*/private static Integer CURRENT_SIZE = 0;/*** 时间一分钟*/static final Long ONE_MINUTE = 60 * 1000L;/*** 永不过期*/private static final Long CACHE_FOREVER = -1L;/*** 缓存对象*/private static final Map<String, CacheObj> CACHE_OBJECT_MAP = new ConcurrentHashMap();/*** 这个记录了缓存使用的最后一次的记录,最近使用的在最前面*/private static final List<String> CACHE_USE_LOG_LIST = new LinkedList();/*** 清理过期缓存是否在运行*/private static volatile Boolean CLEAN_THREAD_IS_RUN = false;/*** 设置缓存** @param cacheKey* @param cacheValue* @param cacheTime*/public static void setCache(String cacheKey, Object cacheValue, long cacheTime) {Long ttlTime = null;if (cacheTime <= 0L) {if (cacheTime == -1L) {ttlTime = -1L;} else {return;}}
//        checkSize();
//        saveCacheUseLog(cacheKey);CURRENT_SIZE = CURRENT_SIZE + 1;if (ttlTime == null) {ttlTime = System.currentTimeMillis() + cacheTime;}CacheObj cacheObj = new CacheObj(cacheValue, ttlTime);CACHE_OBJECT_MAP.put(cacheKey, cacheObj);log.info("have set key :{}", cacheKey);}/*** 设置缓存** @param cacheKey* @param cacheValue*/public static void setCache(String cacheKey, Object cacheValue) {setCache(cacheKey, cacheValue, CACHE_FOREVER);}/*** 获取缓存** @param cacheKey* @return*/public static Object getCache(String cacheKey) {
//        startCleanThread();if (checkCache(cacheKey)) {saveCacheUseLog(cacheKey);return CACHE_OBJECT_MAP.get(cacheKey).getCacheValue();}return null;}public static boolean isExist(String cacheKey) {return checkCache(cacheKey);}/*** 删除所有缓存*/public static void clear() {log.info("have clean all key !");CACHE_OBJECT_MAP.clear();CURRENT_SIZE = 0;}/*** 删除单个缓存** @param cacheKey*/public static void deleteCache(String cacheKey) {Object cacheValue = CACHE_OBJECT_MAP.remove(cacheKey);if (cacheValue != null) {log.info("have delete key : {}", cacheKey);CURRENT_SIZE = CURRENT_SIZE - 1;}}/*** 判断缓存在不在,过没过期** @param cacheKey* @return*/private static boolean checkCache(String cacheKey) {CacheObj cacheObj = CACHE_OBJECT_MAP.get(cacheKey);if (cacheObj == null) {return false;}if (cacheObj.getTtlTime() == -1L) {return true;}if (cacheObj.getTtlTime() < System.currentTimeMillis()) {deleteCache(cacheKey);return false;}return true;}/*** 删除最近最久未使用的缓存*/private static void deleteLRU() {log.info("delete Least recently used run!");String cacheKey = null;synchronized (CACHE_USE_LOG_LIST) {if (CACHE_USE_LOG_LIST.size() >= CACHE_MAX_NUMBER - 10) {cacheKey = CACHE_USE_LOG_LIST.remove(CACHE_USE_LOG_LIST.size() - 1);}}if (cacheKey != null) {deleteCache(cacheKey);}}/*** 删除过期的缓存*/public static void deleteTimeOut() {log.info("delete time out run!");List<String> deleteKeyList = new LinkedList<>();for (Map.Entry<String, CacheObj> entry : CACHE_OBJECT_MAP.entrySet()) {if (entry.getValue().getTtlTime() < System.currentTimeMillis() && entry.getValue().getTtlTime() != -1L) {deleteKeyList.add(entry.getKey());}}for (String deleteKey : deleteKeyList) {deleteCache(deleteKey);}log.info("delete cache count is :{}", deleteKeyList.size());}/*** 检查大小* 当当前大小如果已经达到最大大小* 首先删除过期缓存,如果过期缓存删除过后还是达到最大缓存数目* 删除最久未使用缓存*/private static void checkSize() {if (CURRENT_SIZE >= CACHE_MAX_NUMBER) {deleteTimeOut();}if (CURRENT_SIZE >= CACHE_MAX_NUMBER) {deleteLRU();}}/*** 保存缓存的使用记录** @param cacheKey*/private static synchronized void saveCacheUseLog(String cacheKey) {synchronized (CACHE_USE_LOG_LIST) {CACHE_USE_LOG_LIST.remove(cacheKey);CACHE_USE_LOG_LIST.add(0, cacheKey);}}/*** 设置清理线程的运行状态为正在运行*/public static void setCleanThreadRun() {CLEAN_THREAD_IS_RUN = true;}/*** 开启清理过期缓存的线程*/private static void startCleanThread() {if (!CLEAN_THREAD_IS_RUN) {CleanTimeOutThread cleanTimeOutThread = new CleanTimeOutThread();Thread thread = new Thread(cleanTimeOutThread);//设置为后台守护线程thread.setDaemon(true);thread.start();}}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/216352.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

攻防世界题目练习——Web引导模式(五)(持续更新)

题目目录 1. FlatScience2. bug3. Confusion1 1. FlatScience 参考博客&#xff1a; 攻防世界web进阶区FlatScience详解 题目点进去如图&#xff0c;点击链接只能看到一些论文pdf 用dirsearch和御剑扫描出一些隐藏文件&#xff1a; robots.txt: admin.php: login.php: f…

配电站房智慧化改造

随着科技的发展和工业化自动化的不断提高&#xff0c;传统的配电室已经不能满足现代工业的需求。配电站房的智慧化改造可以提高电力系统的运行效率和安全性&#xff0c;依托电易云-智慧电力物联网实现配电房无人值守。以下是配电站房智慧化改造的一些主要方面&#xff1a; 设备…

数据分享 I 全国市级商品房屋销售数据,shp/excel格式,2005-2020年数据

基本信息. 数据名称: 全国市级商品房屋销售数据 数据格式: Shp、excel 数据时间: 2005-2020年 数据几何类型: 面 数据坐标系: WGS84坐标系 数据来源&#xff1a;网络公开数据 数据字段&#xff1a; 序号字段名称字段说明1spxse商品房销售额&#xff08;亿元&#xf…

css 表示具有特定类或者其他属性的某种标签类型的元素

需求 通过 css 选择器获取某种标签&#xff08;如&#xff1a;div、input 等&#xff09;具有某个属性&#xff08;如&#xff1a;class、id 等&#xff09;的元素&#xff0c;从而修改其样式。 代码 通过 [标签].[属性] 的方式来获取 <div class"test">&l…

合封芯片开发就找宇凡微,提供合封芯片技术支持与资讯

一、引言 随着科技的迅速发展&#xff0c;芯片在各种电子设备中的地位日益凸显&#xff0c;其中越来越受关注的合封芯片给芯片和pcb厂商带来惊喜 合封芯片是指将多个芯片&#xff08;或其他电子元件&#xff09;封装在一个芯片封装体中的芯片。这种封装方式可以实现多个芯片的…

APP自动化测试工具大全

一、UI自动化测试工具 1. uiautomator2 openatx开源的ui自动化工具&#xff0c;支持Android和iOS。主要面向的编程语言是Python&#xff0c;API设计简洁易用&#xff0c;在开源社区也是很受欢迎。 安装&#xff1a; pip install --upgrade --pre uiautomator2# Or you can …

ArcGIS无法绘制一个或多个图层

背景&#xff1a;在导入一份数据时候&#xff0c;arcmap出现无法绘制一个或多个图层的错误&#xff0c;...点数少于要素所要求的的数量&#xff0c;查阅了半天资料发现是制作数据时候拓扑关系错误造成&#xff0c;现将处理方法详细记录如下&#xff1a; 1.原数据&#xff1a; …

北斗卫星助力消防救援实现精确升级

北斗卫星助力消防救援实现精确升级 在浙江省湖州市&#xff0c;当地消防支队建设了基于北斗系统的“智慧用水”等湖州市“智慧消防”综合信息指挥平台&#xff0c;初步实现了火灾精确预警、精确防范、精确指挥和精确处置。 湖州市“智慧用水系统”通过将北斗系统与地理信息管网…

199. 二叉树的右视图 --力扣 --JAVA

题目 给定一个二叉树的 根节点 root&#xff0c;想象自己站在它的右侧&#xff0c;按照从顶部到底部的顺序&#xff0c;返回从右侧所能看到的节点值。 解题思路 List添加元素的顺序可以作为树的层级&#xff1b;将树以根右左的顺序遍历&#xff1b;若当前层级已添加过元素则不…

plf::list原理分析

plf::list是一个比std::list性能要好的另外一种实现&#xff0c;根据作者的性能测试&#xff1a; 293% faster insertion 57% faster erasure 17% faster iteration 77% faster sorting 70% faster reversal 91% faster remove/remove_if 63% faster unique 811% faster clear …

【分享】7-Zip软件如何压缩文件?

7-Zip是一款完全免费的解压缩软件&#xff0c;不仅拥有自己独特的格式&#xff0c;还支持众多主流压缩格式&#xff0c;相比其他解压缩软件&#xff0c;它的压缩率更好&#xff0c;压缩速度更快。今天来分享一下如何使用7-Zip软件来压缩文件。 首先&#xff0c;我们可以到7-Zi…

SpringBoot热部署

SpringBoot热部署 借鉴链接&#x1f517;&#xff1a;SpringBoot中的热部署 添加devtools依赖和pom插件 <!-- devtools 依赖 --> <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId&…

C语言——结构体

一、结构的基础知识 结构是一些值的集合&#xff0c;这些值称为成员变量结构的&#xff0c;每个成员可以是不同类型的变量。 二、结构的声明 struct tag {member-list; }variable-list; 描述一个学生&#xff1a; typedef struct Student {char name[20]; //姓名int age; …

SpringBoot入门及整合

前言 Spring Boot是一个基于Spring框架的快速开发脚手架&#xff0c;它简化了Spring应用的初始化和搭建过程&#xff0c;提供了众多便利的功能和特性并且使用"习惯优于配置"的理念&#xff0c;通过提供默认设置来快速搭建应用&#xff0c;同时也保留了灵活性以进行定…

IntelliJ IDEA创建一个spark的项目

在开始之前&#xff0c;需要说明的是 要跑通基本的wordcount程序&#xff0c;是不需要在windows上安装 hadoop 和spark的&#xff0c;因为idea在跑程序的时候&#xff0c;会按照 pom.xml配置文件&#xff0c;从指定的 repository源&#xff0c;按照properties指定的版本&#x…

系统架构设计师教程(一)绪论

系统架构设计师 1.1 系统架构概述1.1.1 系统架构的定义及发展历程1.1.2 软件架构的常用分类及建模方法1、软件架构常用分类2、系统架构的常用建模方法 1.2 系统架构设计师概述1.3 如何成为一名好的系统架构设计师 1.1 系统架构概述 自1946年第一台计算机诞生以来&#xff0c;计…

LVDS硬件设计

LVDS接口有: 1、四对信号传输差分线&#xff0c;最多传输 4*728bit数据 2、一对时钟。 3、一对差分线有8位&#xff0c;但是最多传输7 bit 的数据。 4、一个LVDS通道只能传输8bit的RGB信号&#xff08;3*8 3 27bit&#xff09;。高于8Bits 就需要两个channel。 5、LVDS的时钟一…

springboot(ssm云上水果超市 水果销售系统Java系统

springboot(ssm云上水果超市 水果销售系统Java系统 开发语言&#xff1a;Java 框架&#xff1a;ssm/springboot vue JDK版本&#xff1a;JDK1.8&#xff08;或11&#xff09; 服务器&#xff1a;tomcat 数据库&#xff1a;mysql 5.7&#xff08;或8.0&#xff09; 数据库…

CSS import 规则

导入 “navigation.css” 样式到当前的样式表&#xff1a; import “navigation.css”; /* 使用字符串 / 或者 import url(“navigation.css”); / 使用 url 地址 */ 属性定义及使用说明 CSS import 用于从其他样式表导入样式规则。 import 规则必须在 CSS 文档的头部&#xff…

react-native 最新版 删除x86配置

针对不同的 CPU 架构生成 APK 以减小 APK 文件的大小 默认情况下&#xff0c;生成的 APK 会同时包含针对于多种 CPU 架构的原生代码。这样可以让我们更方便的向其他人分享这个 APK&#xff0c;因为它几乎可以运行在所有的 Android 设备上。但是&#xff0c;这会导致所有设备上都…