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

使用synchronized关键字同步Java线程

问题

在Java多线程编程中,你需要保护某些数据,防止多个线程同时访问导致数据不一致或程序错误。

解决方案

在需要保护的方法或代码段上使用synchronized关键字。

讨论

synchronized关键字是Java提供的同步机制,用于确保在同一时刻只有一个线程能够执行指定的方法或代码块。这种机制特别适用于保护共享资源,防止多线程并发访问引发的问题。以下是synchronized的主要功能:

  • 对于实例方法synchronized限制同一对象实例中只有一个线程可以执行该方法或其他同步方法。
  • 对于静态方法synchronized限制同一类中只有一个线程可以执行该方法。
  • 对于代码块,可以通过synchronized(object)指定锁定某个对象,只保护特定的代码段。

同步整个方法实现起来更简单且更安全,但可能会因阻塞其他线程而影响性能。如果只需要保护部分代码,可以使用同步代码块以提高效率。

示例:同步方法

以下是一个简单的线程安全列表添加操作示例:

public class SafeList {private Object[] data;private int max = 0;public SafeList(int size) {data = new Object[size];}public synchronized void add(Object obj) {data[max] = obj;max = max + 1;}
}

在这个例子中,add()方法被synchronized修饰,确保同一时刻只有一个线程可以修改data数组,避免数据覆盖或丢失。

未同步的风险

假设我们去掉synchronized,如下:

public void add(Object obj) {data[max] = obj;  // 第一步:存储对象max = max + 1;    // 第二步:递增索引
}

如果线程A在执行第一步后被中断,线程B紧接着运行并执行两步,会覆盖线程A存储的对象。线程A恢复后继续执行第二步,导致max指向一个未初始化的位置。这种情况可能导致数据丢失和数组状态不一致,如下图所示:

正常情况:
data[max] = obj; max = 1;失败情况:
线程A: data[0] = obj1;
线程B: data[0] = obj2; max = 1;
线程A: max = 2; // obj1丢失,data[1]未初始化

即使将两行合并为data[max++] = obj;,问题依然存在,因为线程可能在JVM指令之间被中断。只有使用synchronized才能彻底解决问题。

示例:同步代码块

如果只想同步部分代码,可以使用synchronized代码块。例如:

public class SafeList {private Object[] data;private int max = 0;public SafeList(int size) {data = new Object[size];}public void add(Object obj) {synchronized (data) {data[max] = obj;max = max + 1;}}
}

这里,synchronized (data)确保对data数组的访问是线程安全的,同时未同步的代码(如构造函数)不会阻塞其他线程。

选择同步对象

同步代码块需要指定一个对象作为锁。通常选择与共享资源相关的对象,例如:

  • synchronized(this):锁定当前对象实例。
  • synchronized(data):锁定共享数组。
  • 自定义锁对象:如private final Object lock = new Object();

例如,同步对ArrayList的访问:

public class ListManager {private ArrayList<String> myList = new ArrayList<>();public void process(String item) {synchronized (myList) {if (myList.indexOf(item) != -1) {System.out.println("Item found!");} else {myList.add(item);}}}
}

示例:多线程数组操作

以下代码展示了同步与非同步操作的对比:

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;public class ArrayAdding {private static final int HOWMANY = 1000;private static int[] array;private static ExecutorService pool = Executors.newFixedThreadPool(2);static Runnable runBad = () -> {for (int i = 0; i < array.length; i++) {array[i] = array[i] + i;}};static Runnable runGood = () -> {synchronized (array) {for (int i = 0; i < array.length; i++) {array[i] = array[i] + i;}}};public static void main(String[] args) throws Exception {process("runGood", runGood);process("runBad", runBad);}static void process(String name, Runnable run) throws Exception {System.out.println("Starting: " + name);array = new int[HOWMANY];var t1 = pool.submit(run);var t2 = pool.submit(run);t1.get();t2.get();for (int i = 0; i < array.length; i++) {if (array[i] != 2 * i) {System.out.printf("%d found at offset %d\n", array[i], i);return;}}System.out.println(name + " completed successfully");}
}

运行结果可能如下:

Starting: runGood
runGood completed successfully
Starting: runBad
468 found at offset 468

runGood使用同步,始终正确;runBad未同步,可能因竞态条件失败。这种失败在现实中可能导致严重后果,如Therac-25事件中的辐射治疗事故。

结论

synchronized关键字是Java中保护数据免受多线程并发访问的有效工具。通过同步方法或代码块,可以防止数据不一致和竞态条件。选择同步整个方法还是代码块取决于性能和安全性的权衡。合理的同步设计能显著提升程序的可靠性。

相关文章:

使用synchronized关键字同步Java线程

问题 在Java多线程编程中&#xff0c;你需要保护某些数据&#xff0c;防止多个线程同时访问导致数据不一致或程序错误。 解决方案 在需要保护的方法或代码段上使用synchronized关键字。 讨论 synchronized关键字是Java提供的同步机制&#xff0c;用于确保在同一时刻只有一…...

从头训练小模型: 2 监督微调SFT

简介 从头训练小模型是我个人对大语言模型(LLM)学习中的重要部分。 通过对一个小规模模型的最小化复现实践&#xff0c;我不仅能够深入理解模型训练的基本流程&#xff0c;还可以系统地学习其中的核心原理和实际运行机制。这种实践性的学习方法让我能够直观地感受模型训练的每…...

【QT】QT中http协议和json数据的解析-http获取天气预报

QT中http协议和json数据的解析 1.http协议的原理2.QT中http协议的通信流程2.1 方法步骤 3.使用http协议&#xff08;通过http下载图片和获取天气预报信息&#xff09;3.1 http下载网络上的图片(下载小文件)3.1.1 示例代码3.1.2 现象 3.2 获取网络上天气预报3.2.1 免费的天气预报…...

PiscTrace针对YOLO深度适配:从v8到v12

一、YOLO简介&#xff1a;目标检测的核心技术 YOLO&#xff08;You Only Look Once&#xff09;是近年来最为流行的目标检测模型&#xff0c;凭借其实时性与高精度&#xff0c;广泛应用于自动驾驶、视频监控、安防检测等多个领域。YOLO系列模型自v1问世以来&#xff0c;经过不…...

前端面试每日三题 - Day 24

这是我为准备前端/全栈开发工程师面试整理的第24天每日三题练习&#xff0c;涵盖了&#xff1a; JavaScript 中的 Promise.all()、Promise.race() 和 Promise.allSettled() 的实际应用和性能差异React 中的 Concurrent Rendering 和 useTransition API如何设计一个高并发的在线…...

正态分布习题集 · 题目篇

正态分布习题集 题目篇 全面覆盖单变量正态、多变量正态、参数估计、假设检验、变换以及应用&#xff0c;共 20 题&#xff0c;从基础到进阶。完成后请移步《答案与解析篇》。 1. 基础定义与性质&#xff08;5题&#xff09; 1.1 密度函数 写出正态分布 N ( μ , σ 2 ) N(…...

Three.js在vue中的使用(二)-动画、材质

一、Three.js 动画原理与实现 1. 基本原理 Three.js 的动画系统基于 关键帧&#xff08;Keyframe&#xff09; 和 时间轴&#xff08;AnimationClip&#xff09; 实现&#xff1a; THREE.AnimationMixer&#xff1a;管理多个动画片段的播放器THREE.AnimationClip&#xff1a…...

【办公类-99-04】20250504闵豆统计表excle转PDF,合并PDF、添加中文字体页眉+边框下划线

需求说明 督导检查&#xff0c;各条线都要收集资料。 今天去加班&#xff0c;遇到家教主任&#xff0c;她让我用保教主任的彩色打印机打印这套活跃度表格。&#xff08;2023学年上学期下学期-2024学年上学期&#xff0c;就是202309-202504&#xff09; 每个excle都是内容在A4一…...

ES类迁移方法

快照(s3 file FS)跨集群迁移es-dumpremote-reindexLogstash Elasticsearch 迁移方法 Elasticsearch 迁移是将数据、索引和配置从一个 Elasticsearch 集群转移到另一个集群的过程。以下是几种常见的迁移方法&#xff1a; 1. 快照和恢复 (Snapshot and Restore) 这是最推荐的…...

智能合约部署之全国职业院校技能大赛“区块链技术应用”赛项—“航班延误险案例”

智能合约部署之全国职业院校技能大赛“区块链技术应用”赛项—“航班延误险案例” 1.启动虚拟机上的区块链 (1)打开VMware虚拟机,在桌面中点击右键,选择Open Terminal打开命令行窗口。 (2)使用"cd geth_local/"命令,切换至区块链根目录,输入下面的命令启动…...

STM32外设-GPIO输入(仅数字)

STM32外设-GPIO输入 一&#xff0c;输入的三种类型1. 上拉 (Pull-up)输入2. 下拉 (Pull-down)输入3. 浮空 (Floating / High-Impedance)输入 二&#xff0c;下拉电阻的作用 学完基础的led&#xff0c;接下来学习key即按键&#xff0c;但在连接按键之前&#xff0c;我们必须了解…...

QT开发工具对比:Qt Creator、Qt Designer、Qt Design Studio

前端开发工具—Qt Designer Qt Designer是Qt框架的一部分&#xff0c;是一个图形用户界面设计工具。它允许开发者通过可视化方式设计和布局GUI组件&#xff0c;而无需手动编写UI代码。设计完成后&#xff0c;Qt Designer生成UI文件&#xff08;通常以.ui为扩展名&#xff09;&…...

(ADC)数模转换器的不同类型对比

&#xff08;ADC&#xff09;数模转换器的不同类型对比 数模转换器&#xff08;ADC&#xff09;类型详解1. **并行比较型ADC&#xff08;Flash ADC&#xff09;****工作原理****优缺点****应用场景** 2. **逐次逼近型ADC&#xff08;SAR ADC&#xff09;****工作原理****优缺点…...

MOS管极间电容参数学习

文章目录 前言1. 输入电容&#xff08;Ciss&#xff09;2. 输出电容&#xff08;Coss&#xff09;3. 反向转移电容&#xff08;Crss&#xff09;4&#xff0c;测试条件解读总结 前言 MOS管在电路设计中非常常用&#xff0c;用途包括DC-DC&#xff0c;电平转换等&#xff0c;所…...

Webug4.0靶场通关笔记14- 第18关 文件上传之Nginx解析缺陷

目录 第18关 渗透实战 1.打开靶场 2.构造php脚本 3.源码分析 &#xff08;1&#xff09;客户端源码 &#xff08;2&#xff09;服务的源码 4.Nginx解析法渗透 &#xff08;1&#xff09;缺陷原因 &#xff08;2&#xff09;缺陷条件 &#xff08;3&#xff09;构造脚…...

外观模式(Facade Pattern)

非常好&#xff01;现在我们来讲解结构型设计模式之一&#xff1a;外观模式&#xff08;Facade Pattern&#xff09;。 我会通过&#xff1a; ✅ 简洁定义 &#x1f3af; 为什么需要 &#x1f40d; Python 代码&#xff08;含注释&#xff09; &#x1f9ed; 流程图 应用场…...

Javase 基础加强 —— 03 集合

本系列为笔者学习Javase的课堂笔记&#xff0c;视频资源为B站黑马程序员出品的《黑马程序员JavaAI智能辅助编程全套视频教程&#xff0c;java零基础入门到大牛一套通关》&#xff0c;章节分布参考视频教程&#xff0c;为同样学习Javase系列课程的同学们提供参考。 集合是一种容…...

【React】 Hooks useTransition 解析与性能优化实践

1.背景 useTransition 是 React 18 引入的一个并发模式下的 Hook&#xff0c;用于区分紧急和非紧急的状态更新&#xff0c;提升应用的响应性和用户体验;它可以管理 UI 中的过渡状态&#xff0c;特别是在处理长时间运行的状态更新时。它允许你将某些更新标记为“过渡”状态&…...

C++23 std::tuple与其他元组式对象的兼容 (P2165R4)

文章目录 引言C23 std::tuple概述std::tuple的定义和基本用法std::tuple的特性std::tuple的应用场景 其他元组式对象的特点Python元组的特点Python元组与C std::tuple的对比 P2165R4提案的具体内容提案背景提案主要内容提案的影响 兼容性示例代码总结 引言 在C编程的世界里&am…...

网络Tips20-003

1.E1载波的控制开销占2/32*100%6.25%&#xff0c;E1载波的基本帧传送时间是125uS。 2.计算机在一个指令周期的过程中&#xff0c;为从内存读取指令操作码&#xff0c;首先要将.程序计数器(PC)的内容送到地址总线上 3.3DES算法:密码学中&#xff0c;3DES是三重数据加密算法通称…...

Rust的安全卫生原则

在Rust编程世界里&#xff0c;unsafe关键字常常让初学者感到困惑。他们经常会问&#xff1a;“在unsafe块里能做什么&#xff1f;”“什么时候需要使用unsafe&#xff1f;” 这些问题虽然很常见&#xff0c;但对于真正理解Rust的安全机制来说还远远不够。因为随着Rust操作语义的…...

TestBench激励与待测

TestBench激励与待测 ✅ 一、TestBench 的作用✅ 二、例化的目的✅ 三、TestBench 中的信号类型选择&#x1f7e2; 输入端口&#xff08;input&#xff09; → 在 TestBench 中声明为 reg&#x1f7e1; 输出端口&#xff08;output&#xff09;→ 在 TestBench 中声明为 wire ✅…...

VulnHub-OSCP靶机

前言&#xff1a;由于这台机器过于简单&#xff0c;所以我会尽量细化和介绍每个步骤以及涉及到的知识点&#xff0c;让正在打入门机器的你不在迷茫和硬化的操作&#xff0c;理解并熟悉每条命令以及参数的含义&#xff0c;以及把前期带给我们的信息进行快速筛选&#xff0c;有利…...

【前端】【面试】在 Nuxt.js SSR/SSG 应用开发的 SEO 优化方面,你采取了哪些具体措施来提高页面在搜索引擎中的排名?

在 Nuxt.js 的 SSR&#xff08;服务器端渲染&#xff09;或 SSG&#xff08;静态站点生成&#xff09;应用中&#xff0c;SEO 优化是非常核心的工作内容之一。利用 Nuxt.js 的特性&#xff0c;我们可以通过多个维度系统地提升搜索引擎排名。 下面是我在实际项目中采取的 SEO 优…...

软考 系统架构设计师系列知识点之杂项集萃(53)

接前一篇文章&#xff1a;软考 系统架构设计师系列知识点之杂项集萃&#xff08;52&#xff09; 第85题 在静态测试中&#xff0c;主要是对程序代码进行静态分析。“数据初始化、赋值或引用过程中的异常”属于静态分析中的&#xff08;&#xff09;。 A. 控制流分析 B. 数据…...

【AI面试准备】模型自动化评估经验

面试要求&#xff1a;模型自动化评估经验。 以下是针对模型自动化评估经验的结构化知识总结&#xff0c;涵盖核心概念、工具链、高频考点和面试回答技巧&#xff0c;助你快速掌握关键点&#xff1a; 目录 **一、模型自动化评估的核心逻辑**1. **为什么要自动化评估&#xff1f…...

indexedDB

indexedDB 特点 **容量大&#xff1a;**不同浏览器不一样&#xff0c;250MB **遵守同源策略&#xff1a;**只能访问同源下的数据库&#xff0c;不能跨域 **异步操作&#xff1a;**防止阻塞&#xff08;特别是大量数据的操作&#xff09; 事务支持‌&#xff1a;确保数据的…...

Mybatis学习(下)

目录 1. 动态sql的应用 1.2 1.2 1.3 、 、 标签 1.4 1. 动态sql的应用 使用Mybatis框架时, 对于sql数据的操作量比较大的时候, 看着会觉得很乱, 可能写着写着就乱了, 或者说回过头来发现sql语句写错了, 很麻烦, 所以动态sql就可以让我们用Java代码, 替换部分sql语句 1.2 &l…...

[三分钟学算法]分治-快速排序-最小的K个数:设计一个算法,找出数组中最小的k个数。以任意顺序返回这k个数均可。

文章目录 题目详情算法原理编写代码 题目详情 题目链接 设计一个算法&#xff0c;找出数组中最小的k个数。以任意顺序返回这k个数均可。 示例&#xff1a; 输入&#xff1a; arr [1,3,5,7,2,4,6,8], k 4 输出&#xff1a; [1,2,3,4]提示&#xff1a; 0 < len(arr) <…...

从github的插件直接导入unity

我们随便找个插件&#xff1a; A&#xff1a;处直接下载压缩包文件&#xff0c;或是git下载也可以 B&#xff1a;直接下载打好包也行 我们这里选择直接下好的包 请注意!!!有些版本可能不支持&#xff0c;请找到支持的&#xff0c;对应的历史版本进行下载使用 点击B&#xf…...

Linux | 了解Linux中的任务调度---at与crontab 命令

一. 延迟任务 1.1 延迟任务的发起 -- at命令 at命令执行是调用的是atd服务&#xff0c;即使系统最小化安装atd也会被安装到系统中at 任务信息存放在系统中/var/spool/at目录中at 任务的日志文件被存放到/var/log/cron中at 任务执行时如果遇到系统处于关闭状态&#xff0c;那么…...

多语言笔记系列:Polyglot Notebooks 多种使用方式

.NET Interactive 使用方式 .NET Interactive生态&#xff0c;大约由&#xff1a;前端UI(Jupyter、VSCode等)、交互协议(PMP、JMP)、执行器(.net interactive)和语言服务组成。 有多种组合方式&#xff0c;来使用。最常用的还是 VS Code(Polyglot Notebooks插件)充当前端UI&am…...

TF-IDF算法详解

引言 TF-IDF&#xff08;Term Frequency-Inverse Document Frequency&#xff09;是信息检索和文本挖掘中常用的加权技术&#xff0c;用于评估一个词语对于一个文档集或语料库中某个文档的重要程度。 一、基本概念 1. 组成要素 TF-IDF由两部分组成&#xff1a; TF (Term F…...

C语言实现数据结构:堆排序和二叉树_链式

一.堆的应用 1.堆排序 void test01() {int arr[] { 17,20,10,13,19,15 };int n sizeof(arr) / sizeof(arr[0]);HP p;HPInit(&p);for (int i 0; i < n; i){HPPush(&p, arr[i]);}int i 0;while (!HPEmpty(&p)){arr[i] HPTop(&p);HPPop(&p);}for (i…...

网狐系列三网通新钻石娱乐源码全评:结构拆解、三端实测与本地部署问题记录

本文为基于“网狐系列三网通新钻石娱乐电玩”源码的私测报告&#xff0c;涵盖前后端结构解析、三端测试结果、控制台功能说明、智能机器人机制以及本地部署过程中的真实报错与解决策略。文章目的仅限于源码结构研究和测试用途&#xff0c;不具备任何上线、商用部署条件。 一、源…...

C语言的指针认识

当实参传递给形参时&#xff0c;形参实例化相当于实参的一份临时拷贝 对形参的修改不能改变实参&#xff0c;除非用指针...

iview自定义下拉树菜单

最近由于项目需要&#xff0c;封装了第二种下拉树&#xff0c;带checkBox并且可以支持快速选择的下拉树。样式如下 自定义下拉树菜单.png 所实现交互功能如下&#xff1a; 1.点击对应的层级按钮&#xff0c;自动勾选出对应的所有同级节点。 2.点击自定义&#xff0c;清空所有勾…...

Dubbo(94)如何在金融系统中应用Dubbo?

在金融系统中应用Dubbo&#xff0c;可以通过以下步骤实现&#xff1a; 项目结构设计&#xff1a;规划项目的模块结构&#xff0c;通常包括服务接口模块、各个服务提供者模块&#xff08;如账户服务、交易服务、风控服务等&#xff09;、服务消费者模块&#xff08;如前端应用、…...

Linux:web服务

一、nginx的安装及启用 1、为主机配置IP和搭建软件仓库 &#xff08;1&#xff09;IP的配置 &#xff08;2&#xff09;搭建软件仓库 2、 web服务的安装与启用 &#xff08;1&#xff09;nginx的端口 更改nginx端口号 效果 &#xff08;2&#xff09; 默认发布目录 修改默认发…...

process terminated with status -1073741515

使用CodeBlocks25.03编译wxWidgets3.2.8程序时提示process terminated with status -1073741515 后来自己重新编译生成了一下wxWidgets3.2.8源码&#xff0c;问题得以解决。...

2025信息安全网络安全意识培训资料汇编(24份)

最新整理&#xff1a;2025信息安全网络安全意识培训资料汇编&#xff0c;共24份资料&#xff0c;供学习参考。 互联网信息安全意识培训.pptx100个网络安全风险防范知识.pptx亚信信息安全意识培训.pptx网络安全法规及意识培训.pptx网络安全意识与案例分析.pptx绿盟-安全意识培训…...

线程概念与控制

Linux线程概念 什么是线程 在一个程序里的一个执行路线就叫做线程&#xff08;thread&#xff09;。更准确的定义是&#xff1a;线程是“一个进程内部 的控制序列”&#xff0c;一切进程至少都有一个执行线程&#xff0c;线程在进程内部运行&#xff0c;本质是在进程地址空间内…...

【SpringAI+阿里云百炼】AI对话4个Demo

基于SpringAI和阿里云百炼平台&#xff0c;实现了四个AI对话的小Demo 小团团对话机器人哄哄模拟器培训班智能客服仿ChatPDF 笔记如下:语雀知识笔记《SpringAI》...

Redis-----认识NoSQL

文章目录 前言一、SQL的结构化与NoSQL非结构化1.SQL2.NoSQL 二、关系型数据库SQL与非关系型数据库NoSQL1.SQL2.NoSQL 三、SQL查询与NoSQL查询1.SQL2.NoSQL 四、事务的区别1.SQL2.NoSQL 总结 前言 提示&#xff1a;这里可以添加本文要记录的大概内容&#xff1a; 提示&#xff…...

驱动开发硬核特训 · Day 27(下篇):深入掌握 Common Clock Framework 架构与实战开发

节。 在本篇内容中&#xff0c;我们将围绕 Linux 内核中的时钟子系统核心架构 —— Common Clock Framework&#xff08;简称 CCF&#xff09;展开深入讲解&#xff0c;目标是帮助你全面理解其设计理念、主要数据结构、注册流程、驱动实现方式&#xff0c;以及如何基于 NXP i.M…...

Qt基础知识记录(终篇)

写在前面 博主的项目所需知识已经差不多学完了&#xff0c;后续如果还需要再学习那就继续学&#xff0c;毕竟程序员就是摸着石头过河的&#xff0c;碰壁乃是常有的事情。博主的项目服务器是用MySQL存储数据的&#xff0c;所以博主学习一下Qt如何连接MySQL及从MySQL中存取数据 博…...

LeetCode刷题链表

文章目录 链表总结 常用技巧两数相加题解代码 两两交换链表中的节点题解代码 重排链表题解代码 合并k个升序链表题解代码 K个一组翻转链表题解代码 链表总结 常用技巧 画图 直观 形象 便于理解引入虚拟头节点&#xff0c;便于处理边界情况&#xff0c;方便我们对链表进行…...

transfomer网络构建

目录 整体架构 详细模块分析 Transformer 算法的演进 代码讲解 1. 导入必要的库 2. InputEmbeddings 类 3. PositionalEncoding 类 4. LayerNormalization 类 5. FeedForwardBlock 类 6. MultiHeadAttentionBlock 类 7. ResidualConnection 类 8. EncoderBlock 类 9. Encoder 类…...

【mathematica】常见命令

mathematica官方文档 下载安装 安装激活教程 基本用法 输入、画图、基本运算、方程组求解、公式导出、 笔记本新建&#xff1a; 文件-新建-笔记本 输入&#xff1a; 直接在界面输入定义的变量、式子或者方程组即可 输出&#xff08;计算&#xff09; ENTER : 换行ENTER SHIF…...

photoshop学习笔记2

第一章 第01节-界面的重要性(学习方法) 第02节-文件的打开新建及储存 第03节-移动工具(图层概念) 学习目标&#xff1a; 1.了解图层概念 2.认识工具属性 3.掌握工具使用 图层的概念 移动工具 移动工具就是用来移动图层内容的。是否可以用来移动组…...