synchronized锁字符串

示例一

在没有使用synchronized锁的情况下:

import java.util.HashMap;
import java.util.Map;public class NonSynchronizedSchoolExample {private static final Map<String, Integer> schoolCountMap = new HashMap<>();  // 存储每个学校的交卷数量public static void main(String[] args) {// 创建三个线程,模拟不同学校的学生交卷Thread thread1 = new Thread(new SubmitPaperTask("西华师范大学"), "Thread-1");Thread thread2 = new Thread(new SubmitPaperTask("西南石油大学"), "Thread-2");Thread thread3 = new Thread(new SubmitPaperTask("西南石油大学"), "Thread-3");thread1.start();thread2.start();thread3.start();}// 创建任务类,模拟学生交卷static class SubmitPaperTask implements Runnable {private final String school;public SubmitPaperTask(String school) {this.school = universityName;}@Overridepublic void run() {// 直接访问并修改 HashMap,未考虑线程安全Integer count = schoolCountMap.get(school);if (count == null) {count = 0;  // 如果没有该学校的记录,默认值为0}// 模拟学生交卷System.out.println(school + " 的学生正在交卷...");try {Thread.sleep(1000);  // 模拟交卷时间schoolCountMap.put(school, count + 1);  // 增加该学校的交卷数量System.out.println(school + " 的学生交卷完毕! 当前交卷数量: " + (count + 1));} catch (InterruptedException e) {e.printStackTrace();}}}
}

在没有使用synchronized的情况下,结果可能出现:

西华师范大学 的学生正在交卷...
西南石油大学 的学生正在交卷...
西华师范大学 的学生交卷完毕! 当前交卷数量: 1
西南石油大学 的学生交卷完毕! 当前交卷数量: 1
西南石油大学 的学生正在交卷...
西南石油大学 的学生交卷完毕! 当前交卷数量: 1

示例二

使用synchronized锁的情况下:

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;@RestController
public class SynchronizedSchoolController {// 存储每个学校的交卷数量private static final Map<String, Object> lockMap = new HashMap<>();  // 存储每个学校的锁对象// 接收交卷请求@GetMapping("/submitPaper/{school}")public String submitPaper(@PathVariable String school) {synchronized (this) {  // 锁住该学校的锁对象// 获取当前学校的交卷数量,如果没有则初始化为0Integer count = schoolCountMap.get(school);if (count == null) {count = 0;  // 如果没有该学校的记录,默认值为0}// 模拟学生交卷try {Thread.sleep(1000);  // 模拟交卷时间schoolCountMap.put(school, count + 1);  // 增加该学校的交卷数量return school + " 的学生交卷完毕! 当前交卷数量: " + (count + 1);} catch (InterruptedException e) {e.printStackTrace();return "交卷失败!";}}}
}

在这种情况下,synchronized锁住的当前实例对象,在这种情况下,我们都每一个线程都是串行执行的。

示例三:

我现在想要改进代码,我可以用synchronized锁住(school)这个字符串,这样不同学校的线程就是并行的,相同学校的就是串行执行的

。。。
synchronized (school)
。。。

使用synchronized锁school字符串的情况下,如果我们使用http接口的发送去请求的话,spring的底层不是发送传递的“西华师范大学”“西南石油大学”这样的字符串常量,而是通过new String(“西华师范大学”)这样的方式去传递string对象。这种情况下锁的资源是三个不同的对象,没有同一个资源的互斥,就会发送并行。

这涉及到 字符串池(String Pool)和 字符串对象的创建方式:

字符串常量(字符串池)

在 Java 中,字符串常量(例如 "西华师范大学")会被存储在一个特殊的内存区域,称为 字符串池。当你创建一个字符串常量时,JVM 会检查池中是否已经存在相同的字符串对象,如果存在,就会返回池中的引用,否则将该字符串放入池中。

String str1 = "西华师范大学";  // 会被存储在字符串池中
String str2 = "西华师范大学";  // str1 和 str2 引用同一个对象

通过 new String() 创建字符串对象

通过 new String("西华师范大学") 创建的字符串对象不再从字符串池中获取对象,而是直接在堆内存中创建一个新的 String 对象。这意味着,每次调用 new String() 都会创建一个新的对象,即使其内容与字符串池中的常量相同。

String str1 = new String("西华师范大学");  // 会在堆中创建一个新的 String 对象
String str2 = new String("西华师范大学");  // str1 和 str2 引用不同的对象

所以直接synchronized (school)还是会出现异常。

 

示例四:

为了解决示例三的问题,我们想到了直接synchronized ()字符串常量。 因为字符串常量都是存放在字符串常量池当中的,是唯一的,能够形成资源互斥。

synchronized(school.intern())

但是字符串常量池里面的字符串是全局唯一的,可能会阻塞相同锁资源的不同操作,所以进一步改进:

我们通过ConcurrentMap创建一个锁对象

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;@RestController
public class SynchronizedSchoolController {// 使用 ConcurrentHashMap,确保线程安全private static final ConcurrentMap<String, Integer> schoolCountMap = new ConcurrentHashMap<>();  // 存储每个学校的交卷数量private static final ConcurrentMap<String, Object> lockMap = new ConcurrentHashMap<>();  // 存储每个学校的锁对象// 接收交卷请求@GetMapping("/submitPaper/{school}")public String submitPaper(@PathVariable String school) {// 获取每个学校的锁对象,确保每个学校有独立的锁Object lock = lockMap.computeIfAbsent(school, key -> new Object());synchronized (lock) {  // 锁住该学校的锁对象// 获取当前学校的交卷数量,如果没有则初始化为0Integer count = schoolCountMap.get(school);if (count == null) {count = 0;  // 如果没有该学校的记录,默认值为0}// 模拟学生交卷try {Thread.sleep(1000);  // 模拟交卷时间schoolCountMap.put(school, count + 1);  // 增加该学校的交卷数量return school + " 的学生交卷完毕! 当前交卷数量: " + (count + 1);} catch (InterruptedException e) {e.printStackTrace();return "交卷失败!";}}}
}

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

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

相关文章

1.14作业

1 if($x[scheme]http||$x[scheme]https){ $ip gethostbyname($x[host]); echo </br>.$ip.</br>; if(!filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE)) {die(ip!); }echo file_get_contents($_POST[url]);可以DNS重…

Hopper架构 GEMM教程

一 使用 1.1 makefile compile:nvcc -arch=sm_90a -lcuda -lcublas -std=c++17 matmul_h100_optimal.cu -o testrun:./test加入-lcublas,不然会有函数无法被识别 二 代码分析 2.1 kernel外参数分析 2.1.1 基本参数 constexpr int BM = 64*2;constexpr int BN = 256;cons…

DeepSeek模型快速部署教程-搭建自己的DeepSeek

前言&#xff1a;在人工智能技术飞速发展的今天&#xff0c;深度学习模型已成为推动各行各业智能化转型的核心驱动力。DeepSeek 作为一款领先的 AI 模型&#xff0c;凭借其高效的性能和灵活的部署方式&#xff0c;受到了广泛关注。无论是自然语言处理、图像识别&#xff0c;还是…

数据仓库、数据湖和数据湖仓

数据仓库、数据湖和数据湖仓是三种常见的数据存储和管理技术&#xff0c;各自有不同的特点和适用场景。以下是它们的详细比较&#xff1a; 1. 数据仓库&#xff08;Data Warehouse&#xff09; 定义&#xff1a;用于存储结构化数据&#xff0c;经过清洗、转换和建模&#xff…

学习aigc

DALLE2 论文 Hierarchical Text-Conditional Image Generation with CLIP Latents [2204.06125] Hierarchical Text-Conditional Image Generation with CLIP LatentsAbstract page for arXiv paper 2204.06125: Hierarchical Text-Conditional Image Generation with CLIP L…

POI pptx转图片

前言 ppt页面预览一直是个问题&#xff0c;office本身虽然有预览功能但是收费&#xff0c;一些开源的项目的预览又不太好用&#xff0c;例如开源的&#xff1a;kkfileview pptx转图片 1. 引入pom依赖 我这个项目比较老&#xff0c;使用版本较旧 <dependency><gro…

零基础学python--------第三节:Python的流程控制语法

Python&#xff0c;浮点数 11.345(单&#xff1a;4个字节&#xff0c; 双&#xff1a;8个字节) 。 十进制的数字25 ---> 11001 讲一个小数转化为二进制&#xff1a; 不断的乘以2 。取整数部分。 十进制的0.625 ----> 二进制&#xff1a; 0&#xff0c; 101 。 0.3 ---…

2025.2.21 Restless And Brave

今天是2025年的2月21日&#xff0c;星期五。 距离考研出分还有两天半的时间。 这种时候&#xff0c;我想考的特别好的同学或者考的特别差的同学都不会太焦虑&#xff0c;只有我这种考的不上不下的人才会焦虑。 我曾不止一次的想过如何面对失败&#xff0c;但每每想到这个问题…

骶骨神经

骶骨肿瘤手术后遗症是什么_39健康网_癌症 [健康之路]匠心仁术&#xff08;七&#xff09; 勇闯禁区 骶骨肿瘤切除术

DeepSeek智能测试知识库助手PRO版:多格式支持+性能优化

前言 测试工程师在管理测试资产时,需要面对多种文档格式、大量文件分类及知识库的构建任务。为了解决这些问题,我们升级了 DeepSeek智能测试知识库助手,不仅支持更多文档格式,还加入了 多线程并发处理 和 可扩展格式支持,大幅提升处理性能和灵活性。 主要功能亮点: 多格…

Ubuntu编译ZLMediaKit

下载 git clone https://gitee.com/xia-chu/ZLMediaKit cd ZLMediaKit git submodule update --init安装工具 sudo apt install -y build-essential sudo apt install -y gcc g sudo apt install -y cmakesudo apt install -y build-essential cmake git libssl-dev libsdl1.…

如何做接口自动化测试?

一、前言 接口通俗来讲就是前端和后段之间传输数据的桥梁&#xff0c;注意&#xff1a;不是每一个项目都有接口&#xff0c;一些大型项目是前后端分离的&#xff0c;那么他们怎么实现数据的传递和返回呢&#xff1f;在通俗来讲就是前端和后段都有一个模拟参数数据 二、接口自…

数据分析和数据挖掘的工作内容

基本的数据分析工作通常包含以下几个方面的内容&#xff1a; 确定目标&#xff08;输入&#xff09;&#xff1a;理解业务&#xff0c;确定指标口径。获取数据&#xff1a;数据仓库&#xff08;SQL提数&#xff09;、电子表格、三方接口、网络爬虫、开放数据集等。清洗数据&am…

基于Python+Vue开发的反诈视频宣传管理系统源代码

项目简介 该项目是基于PythonVue开发的反诈视频宣传管理系统&#xff08;前后端分离&#xff09;&#xff0c;这是一项为大学生课程设计作业而开发的项目。该系统旨在帮助大学生学习并掌握Python编程技能&#xff0c;同时锻炼他们的项目设计与开发能力。通过学习基于Python的反…

StarRocks FE leader节点CPU使用率周期性的忽高忽低问题分析

背景 本文基于 StarRocks 3.3.5 最近在做一些 StarRocks 相关的指标监控的时候&#xff0c;看到了FE master的CPU使用率相对其他FE节点是比较高的&#xff0c;且 呈现周期性的变化&#xff08;周期为8分钟&#xff09;&#xff0c; 于此同时FE master节点的GC频率相对于其他节…

第37章 合作之路与占坑成功

在春寒料峭的时节&#xff0c;那丝丝寒意宛如一缕缕若有若无的轻烟&#xff0c;在空气中悄然弥漫。锐创所的会议室&#xff0c;宛如一个被岁月尘封的神秘空间&#xff0c;暖黄色的灯光晕染开来&#xff0c;像是为整个房间披上了一层朦胧的薄纱&#xff0c;陈旧却又带着几分温馨…

Webpack打包优化

在使用 Webpack 打包项目时&#xff0c;随着项目规模的扩大&#xff0c;构建时间和打包产物的体积可能会逐渐增加。为了提高构建性能和减小打包产物的体积&#xff0c;可以采取以下几种 Webpack 打包优化 的方法。 1. 使用 mode 配置 Webpack 通过 mode 配置来指定构建模式。…

计算机专业知识【深入理解IP网段:192.168.1.1/24 与 192.168.1.0/24】

在网络世界里&#xff0c;IP地址和网段是非常基础却又至关重要的概念。很多朋友在看到类似 192.168.1.1/24 和 192.168.1.0/24 这样的表述时&#xff0c;可能会感到困惑。今天&#xff0c;我们就来详细剖析一下它们的含义以及两者之间的关系。 一、IP地址与子网掩码基础 在深…

python的if判断和循环语句(while循环和for循环)

1.if判断 1.1if判断的基本格式 if 判断条件&#xff1a; 满足条件做的事 score input("请输入成绩&#xff1a;") if score 100:print("你真棒") if score 60:print("还要加油") 使用input输入默认类型为字符串类型 1.2运算符 1.2…

洛谷P9240 [蓝桥杯 2023 省 B] 冶炼金属

题目描述 小蓝有一个神奇的炉子用于将普通金属 O 冶炼成为一种特殊金属 X。这个炉子有一个称作转换率的属性 V&#xff0c;V 是一个正整数&#xff0c;这意味着消耗 V 个普通金属 O 恰好可以冶炼出一个特殊金属 X&#xff0c;当普通金属 O 的数目不足 V 时&#xff0c;无法继续…