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.pswp.cn/bicheng/71587.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/71587.shtml
英文地址,請注明出處:http://en.pswp.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;無法繼續…