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

java常见的几种并发安全问题及解决方案

项目场景:

并发的应用场景,在开发过程会经常遇到。
例如:服务应用启动后,需要简单统计接口的总访问量;实时更新订单状态,成交总额。


问题描述:

比如统计接口访问次数,如下的实现,在并发访问下,统计是不准确的 。

		private int viewCount = 0;private void addViewCount(){viewCount++;}

比如A、B两个线程同时访问,各自从JVM主存中加载变量viewCount到线程内存里viewCount的值都是0,各自+1,更新会JVM主存的也是1。实际A、B执行完毕后,JVM的值应该是2才对。


解决方案:

在这里插入图片描述
并发问题解决,实际有2种方式:有锁、无锁。
有锁的就是关键字synchronized,以及可重入锁ReentrantLock。
无锁的,就是局部变量、不可变对象、CAS原子类、ThreadLocal,共四种。


具体解决方案分析:

一.无锁方式

1.局部变量

    /*** 局部变量,多线程更新count的时候,各自在线程内存中创建i变量。*/public void localParam(){int count = 0;/*本次处理业务,统计*/count++;System.out.println(count);}

2.不可变对象

车辆位置实时更新,传统的setY,setY,在并发过程会出差错。定义一个final localtion类,并且构造函数直接初始化x,y。
/*** 车辆位置经纬度值*/
public final class Location {private final double x;private final double y;public Location(double x, double y) {this.x = x;this.y = y;}
}
同时定义一个traker类,来存储多个车辆的位置信息,更新的时候直接用新的location位置类,去update ConcurrentHashMap。
/*** 不可变类,实现并发更新安全* 通过每次更新位置,直接初始化一个全新的location,然后set到车辆位置map中*/
public class CarLocationTracker {/*** 车辆编码对应车辆位置信息map* ConcurrentHashMap,是利用CAS+synchronized来保证并发安全*/private Map<String, Location> locationMap = new ConcurrentHashMap<>();/*** 更新车辆位置** @param carCode     车辆编码* @param newLocation 车辆新位置*/public void updateLocation(String carCode, Location newLocation) {locationMap.put(carCode, newLocation);}/*** 获取车辆位置** @param carCode 车辆斌吗* @return*/public Location getLocation(String carCode) {return locationMap.get(carCode);}
}

3.ThreadLocal

ThreadLocal 变量,线程局部变量.同一个ThreadLocal所包含的对象,在不同线程中有不同的副本。
	private static final ThreadLocal threadCount= new ThreadLocal();/*** ThreadLocal 变量,线程局部变量*/public void threadLocalParam(){Integer count = (Integer) threadCount.get();/*本次处理业务,统计*/count++;System.out.println(count);}

4.CAS原子类

CAS 机制,三个基本操作:内存地址V,旧的预期值A,要修改的新值B,只有当内存地址V所对应的值与旧的预期值A相等,才会将内存地址V对应的值更新为B。
    private AtomicInteger counter = new AtomicInteger(0);/*** cas 原子类,是个乐观锁,并发性能很高。通过compare and swap比较并置换的原子性设计,read 从jvm主存中读取旧值oldV,* 更新的时候,先比较oldV与主存中的v是否相等,相等就把newV更新替换v;如果不相等,继续while循环,从主存读取'新的'旧值oldV。** 底层是c++实现,保证三个步骤执行在硬件级别,是原子性,要么三个一起执行成功,又不继续循环直到成功。*/public void atomicAdd(){//比如接口访问总次数统计System.out.println(counter.incrementAndGet());}

二.有锁方式

1. 关键字synchronized

	//访问统计private int viewCount = 0;public synchronized void syncAdd(){addViewCount();}private void addViewCount(){viewCount++;}

2. 可重入锁ReentrantLock

	//悲观锁private ReentrantLock lock = new ReentrantLock();//访问统计private int viewCount = 0;private void addViewCount(){viewCount++;}/*** 通过执行方法前,加锁;执行完毕主动释放锁保证int++ 并发安全*/public void lockAdd(){lock.lock();try {addViewCount();} finally {lock.unlock();}}

相关文章:

java常见的几种并发安全问题及解决方案

项目场景&#xff1a; 并发的应用场景&#xff0c;在开发过程会经常遇到。 例如&#xff1a;服务应用启动后&#xff0c;需要简单统计接口的总访问量&#xff1b;实时更新订单状态&#xff0c;成交总额。 问题描述&#xff1a; 比如统计接口访问次数&#xff0c;如下的实现&a…...

介绍一下安装时情况 kubernetes 集群

1.安装命令执行完毕 最开始告诉我们应用的版本 v1.29.14前置检测下载镜像写入证书因为当前我们所有的 kubernetes 集群的组件之间的联通 都是基于HTTPS协议实现的 补充知识点&#xff1a;BS架构&#xff0c;即Browser/Server&#xff08;浏览器/服务器&#xff09;架构模式&a…...

Dify部署踩坑指南(Windows+Mac)

组件说明 Dify踩坑及解决方案 ⚠️ 除了修改镜像版本&#xff0c;nginx端口不要直接修改docker-compose.yaml &#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01; 1、更换镜像版本 这个文件是由.env自动生成的&#xff0c;在.env配置 …...

安科瑞新能源充电桩解决方案:驱动绿色未来,赋能智慧能源

安科瑞顾强 引言 在“双碳”目标与新能源汽车产业高速发展的双重驱动下&#xff0c;充电基础设施正成为能源转型的核心环节。安科瑞电气股份有限公司凭借在电力监控与能效管理领域20余年的技术积淀&#xff0c;推出新一代新能源充电桩解决方案&#xff0c;以智能化、高兼容性…...

深入剖析Java代理模式:静态代理与动态代理的实战应用

代理模式是Java开发中最重要的设计模式之一,广泛应用于性能监控、访问控制、日志记录等场景。本文将带你全面掌握代理模式的实现原理,并通过3种不同的代码实现方式,彻底理解这一核心设计模式的应用技巧。 一、代理模式的核心价值 代理模式(Proxy Pattern)通过创建代理对…...

JVM与性能调优详解

以下是关于 JVM与性能调优 的详细解析&#xff0c;结合理论、实践及常见问题&#xff0c;分多个维度展开&#xff1a; 一、JVM性能调优的核心目标 性能调优的核心目标是通过优化内存管理、垃圾回收&#xff08;GC&#xff09;策略和线程管理&#xff0c;实现以下平衡&#xff…...

【嵌入式通信协议】串口的详细介绍

以下是对嵌入式STM单片机通信串口的详细介绍 一、STM32串口通信基础 STM32的串口模块称为USART(Universal Synchronous/Asynchronous Receiver/Transmitter),支持同步和异步通信;而UART(Universal Asynchronous Receiver/Transmitter)仅支持异步通信。STM32F103C8T6包含…...

乐鑫打造全球首款 PSA Certified Level 2 RISC-V 芯片

乐鑫科技 (688018.SH) 荣幸宣布 ESP32-C6 于 2025 年 2 月 20 日获得 PSA Certified Level 2 认证。这一重要突破使 ESP32-C6 成为全球首款基于 RISC-V 架构获此认证的芯片&#xff0c;体现了乐鑫致力于为全球客户提供安全可靠、性能卓越的物联网解决方案的坚定承诺。 PSA 安全…...

Go学习笔记:基础语法3

1. 常量 Go语言中的常量使用关键字const定义&#xff0c;用于存储不会改变的数据&#xff0c;常量是在编译时被创建的&#xff0c;即使定义在函数内部也是如此&#xff0c;并且只能是布尔型、数字型&#xff08;整数型、浮点型和复数&#xff09;和字符串型。 由于编译时的限…...

虚拟卡 WildCard (野卡) 保姆级开卡教程

本文首发于只抄博客&#xff0c;欢迎点击原文链接了解更多内容。 前言 本篇教程为 WildCard 的介绍以及开卡教学&#xff0c;要了解不同平台&#xff08;Grok、Talkatone 等&#xff09;的订阅方式请移步《订阅教程》分类 当我们想要充值国外平台会员时&#xff0c;一般都需要使…...

机试准备第10天

首先学习二分搜索法。使用二分查找需要先排序。第一题是查找&#xff0c;现学现卖。 //二分查找 #include <stdio.h> #include <vector> #include <algorithm> using namespace std; int main(){int n;scanf("%d", &n);vector<int> a(n…...

Apache ECharts介绍(基于JavaScript开发的开源数据可视化库,用于创建交互式图表)

文章目录 Apache ECharts 介绍功能概览多种图表类型- **基础类型**&#xff1a;折线图、柱状图、饼图、散点图。- **高级类型**&#xff1a;雷达图、热力图、桑基图、K线图。- **地理可视化**&#xff1a;支持地图&#xff08;如中国、世界&#xff09;和地理坐标系。- **3D支持…...

最新版本TOMCAT+IntelliJ IDEA+MAVEN项目创建(JAVAWEB)

前期所需&#xff1a; 1.apache-tomcat-10.1.18-windows-x64&#xff08;tomcat 10.1.8版本或者差不多新的版本都可以&#xff09; 2.IntelliJ idea 24年版本 或更高版本 3.已经配置好MAVEN了&#xff08;一定先配置MAVEN再搞TOMCAT会事半功倍很多&#xff09; 如果有没配置…...

Linux - 进程通信

一、管道 管道是一种进程间通信&#xff08;IPC&#xff09;机制&#xff0c;用于在进程之间传递数据。它的本质是操作系统内核维护的一个内存缓冲区&#xff0c;配合文件描述符进行数据的读写。尽管管道的核心是内存缓冲区&#xff0c;但操作系统通过对管道的实现&#xff0c…...

使用 Arduino 的 WiFi 控制机器人

使用 Arduino 的 WiFi 控制机器人 这次我们将使用 Arduino 和 Blynk 应用程序制作一个 Wi-Fi 控制的机器人。这款基于 Arduino 的机器人可以使用任何支持 Wi-Fi 的 Android 智能手机进行无线控制。 为了演示 Wi-Fi 控制机器人&#xff0c;我们使用了一个名为“Blynk”的 Andr…...

网络安全等级保护2.0 vs GDPR vs NIST 2.0:全方位对比解析

在网络安全日益重要的今天&#xff0c;各国纷纷出台相关政策法规&#xff0c;以加强信息安全保护。本文将对比我国网络安全等级保护2.0、欧盟的GDPR以及美国的NIST 2.0&#xff0c;分析它们各自的特点及差异。 网络安全等级保护2.0 网络安全等级保护2.0是我国信息安全领域的一…...

verb words

纠正correct remedy 修正modify 协商 confer 磋商/谈判 negotiate 通知notice notify *宣布announce 声明declare 宣告 declare *颁布 promulgate /introduce 协调coordinate 评估evaluate assess 撤离evacuate *规定stipulate 参与participate&#xff0c; 涉及refer…...

unity console日志双击响应事件扩展

1 对于项目中一些比较长的日志&#xff0c;比如前后端交互协议具体数据等&#xff0c;这些日志内容可能会比较长&#xff0c;在unity控制面板上查看不是十分方便&#xff0c;我们可以对双击事件进行扩展&#xff0c;将日志保存到一个文本中&#xff0c;然后用系统默认的文本查看…...

维度建模维度表技术基础解析(以电商场景为例)

维度建模维度表技术基础解析(以电商场景为例) 维度表是维度建模的核心组成部分,其设计直接影响数据仓库的查询效率、分析灵活性和业务价值。本文将从维度表的定义、结构、设计方法及典型技术要点展开,结合电商场景案例,深入解析其技术基础。 1. 维度表的定义与作用 定义…...

Leetcode 264-丑数/LCR 168/剑指 Offer 49

题目描述 我们把只包含质因子 2、3 和 5 的数称作丑数&#xff08;Ugly Number&#xff09;。求按从小到大的顺序的第 n 个丑数。 示例: 说明: 1 是丑数。 n 不超过1690。 题解 动态规划法 根据题意&#xff0c;每个丑数都可以由其他较小的丑数通过乘以 2 或 3 或 5 得到…...

【Linux】shell脚本忽略错误继续执行

在 shell 脚本中&#xff0c;可以使用 set -e 命令来设置脚本在遇到错误时退出执行。如果你希望脚本忽略错误并继续执行&#xff0c;可以在脚本开头添加 set e 命令来取消该设置。 举例1 #!/bin/bash# 取消 set -e 的设置 set e# 执行命令&#xff0c;并忽略错误 rm somefile…...

云计算——弹性云计算器(ECS)

弹性云服务器&#xff1a;ECS 概述 云计算重构了ICT系统&#xff0c;云计算平台厂商推出使得厂家能够主要关注应用管理而非平台管理的云平台&#xff0c;包含如下主要概念。 ECS&#xff08;Elastic Cloud Server&#xff09;&#xff1a;即弹性云服务器&#xff0c;是云计算…...

涂鸦T5AI手搓语音、emoji、otto机器人从入门到实战

“&#x1f916;手搓TuyaAI语音指令 &#x1f60d;秒变表情包大师&#xff0c;让萌系Otto机器人&#x1f525;玩出智能新花样&#xff01;开整&#xff01;” &#x1f916; Otto机器人 → 直接点明主体 手搓TuyaAI语音 → 强调 自主编程/自定义 语音控制&#xff08;TuyaAI…...

Spring AI与Spring Modulith核心技术解析

Spring AI核心架构解析 Spring AI&#xff08;https://spring.io/projects/spring-ai&#xff09;作为Spring生态中的AI集成框架&#xff0c;其核心设计理念是通过模块化架构降低AI应用的开发复杂度。与Python生态中的LangChain/LlamaIndex等工具类似&#xff0c;但特别为多语…...

精益数据分析(97/126):邮件营销与用户参与度的关键指标优化指南

精益数据分析&#xff08;97/126&#xff09;&#xff1a;邮件营销与用户参与度的关键指标优化指南 在数字化营销时代&#xff0c;邮件列表效度、用户参与度和网站性能等指标往往决定着创业公司的增长成败。今天&#xff0c;我们将深入解析邮件打开率、网站可用性、页面参与时…...

群晖NAS如何在虚拟机创建飞牛NAS

套件中心下载安装Virtual Machine Manager 创建虚拟机 配置虚拟机 飞牛官网下载 https://iso.liveupdate.fnnas.com/x86_64/trim/fnos-0.9.2-863.iso 群晖NAS如何在虚拟机创建飞牛NAS - 个人信息分享...

HubSpot推出与ChatGPT的深度集成引发兴奋与担忧

上周三&#xff0c;HubSpot宣布已构建与ChatGPT的深度集成&#xff0c;这一消息在HubSpot用户和营销技术观察者中引发了极大的兴奋&#xff0c;但同时也存在一些关于数据安全的担忧。 许多网络声音声称&#xff0c;这对SaaS应用程序和人工智能而言是一场范式转变。 但向任何技…...

2025年低延迟业务DDoS防护全攻略:高可用架构与实战方案

一、延迟敏感行业面临的DDoS攻击新挑战 2025年&#xff0c;金融交易、实时竞技游戏、工业物联网等低延迟业务成为DDoS攻击的首要目标。攻击呈现三大特征&#xff1a; AI驱动的自适应攻击&#xff1a;攻击流量模拟真实用户行为&#xff0c;差异率低至0.5%&#xff0c;传统规则引…...

Linux基础开发工具——vim工具

文章目录 vim工具什么是vimvim的多模式和使用vim的基础模式vim的三种基础模式三种模式的初步了解 常用模式的详细讲解插入模式命令模式模式转化光标的移动文本的编辑 底行模式替换模式视图模式总结 使用vim的小技巧vim的配置(了解) vim工具 本文章仍然是继续讲解Linux系统下的…...

工厂方法模式和抽象工厂方法模式的battle

1.案例直接上手 在这个案例里面&#xff0c;我们会实现这个普通的工厂方法&#xff0c;并且对比这个普通工厂方法和我们直接创建对象的差别在哪里&#xff0c;为什么需要一个工厂&#xff1a; 下面的这个是我们的这个案例里面涉及到的接口和对应的实现类&#xff1a; 两个发…...