Java并发迷宫:同步的魔法与死锁的诅咒
在Java编程的宇宙中,有一个充满神秘与挑战的维度——并发编程。它如同一座错综复杂的迷宫,每个角落都潜藏着惊喜与陷阱。在这篇博客里,我们将一起探索这座迷宫的深处,揭开同步的魔法与死锁的诅咒。
第一章:同步魔法的诞生
同步,是并发编程中最基础也是最重要的概念之一。它就像是一座桥梁,连接着多个线程的世界,确保数据的一致性和完整性。在Java中,synchronized关键字是最常见的同步魔法,它能将普通的方法或者代码块变成一把锁,保护共享资源免受多线程的侵扰。
示例代码:
public class MagicCounter {private int count = 0;public synchronized void increment() {// 这里是一个临界区,每次只允许一个线程进入count++;}public synchronized int getCount() {// 同步读取count的值,确保数据一致性return count;}
}
第二章:死锁的诅咒
然而,同步魔法虽强,但若使用不当,便会招致死锁的诅咒。死锁是一种极端情况,发生在两个或多个线程无限期地等待彼此持有的资源释放,导致整个系统陷入僵局。
死锁示例:
class KeyA {synchronized void useKeyB(KeyB b) {System.out.println("KeyA trying to use KeyB");try { Thread.sleep(100); } catch (InterruptedException e) {}b.useKeyA(this);}
}class KeyB {synchronized void useKeyA(KeyA a) {System.out.println("KeyB trying to use KeyA");try { Thread.sleep(100); } catch (InterruptedException e) {}a.useKeyB(this);}
}
在这个例子中,两个线程分别持有了KeyA和KeyB的锁,并试图获取对方的锁。由于它们都无法释放自己持有的锁,因此陷入了死锁。
第三章:解锁同步的智慧
要避免死锁的诅咒,我们需要掌握更高级的同步技巧。在Java中,java.util.concurrent包提供了多种工具,如ReentrantLock、Semaphore和Condition,它们提供了比synchronized更精细的控制能力。
ReentrantLock示例:
import java.util.concurrent.locks.ReentrantLock;public class SmartCounter {private final ReentrantLock lock = new ReentrantLock();private int count = 0;public void increment() {lock.lock();try {count++;} finally {lock.unlock();}}public int getCount() {lock.lock();try {return count;} finally {lock.unlock();}}
}
ReentrantLock不仅提供了可中断的锁获取,还允许公平锁和非公平锁的选择,使得同步策略更加灵活。
第四章:条件变量与信号量的魅力
除了锁之外,Java还提供了条件变量(Condition)和信号量(Semaphore),它们能够实现更复杂的同步模式。条件变量允许线程在特定条件下等待,而信号量则用于控制对一组相关资源的访问。
Semaphore示例:
import java.util.concurrent.Semaphore;public class SemaphoreExample {private static final Semaphore semaphore = new Semaphore(5);public static void main(String[] args) {for (int i = 0; i < 10; i++) {new Thread(() -> {try {semaphore.acquire();System.out.println(Thread.currentThread().getName() + " is accessing a resource.");Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();} finally {semaphore.release();}}).start();}}
}
在这个例子中,信号量限制了同时访问资源的线程数量,有效地避免了资源争抢。
相关文章:
Java并发迷宫:同步的魔法与死锁的诅咒
在Java编程的宇宙中,有一个充满神秘与挑战的维度——并发编程。它如同一座错综复杂的迷宫,每个角落都潜藏着惊喜与陷阱。在这篇博客里,我们将一起探索这座迷宫的深处,揭开同步的魔法与死锁的诅咒。 第一章:同步魔法的…...
CoderGuide
CoderGuide是一个针对同学们前后端求职面试的开源项目,作为一名互联网/IT从业人员,经常需要搜索一些书籍、面试题等资源,在这个过程中踩过很多坑、浪费过很多时间。欢迎大家 Watch、Star,供各位同学免费使用,永不收费&…...
链式二叉树
链式二叉树,也称为二叉链表,是数据结构中一种非常重要的树形结构表示方法。在链式二叉树中,每个节点不仅包含数据域,还包含两个指针域,分别指向其左子节点和右子节点。这种结构允许二叉树动态地增长和缩减,…...
PHP高校迎新系统-计算机毕业设计源码08468
摘要 随着高校规模的不断扩大和新生人数的增加,传统的手工登记和管理方式已经无法满足高效、准确的需求。为了提升大学新生入学迎新工作的效率和质量,本研究设计开发了一套高校迎新系统。系统通过信息技术的应用,集成了首页、交流论坛、通知公…...
泛微开发修炼之旅--41Ecology基于触发器实现增量数据同步(人员、部门、岗位、人员关系表、人岗关系表)
一、需求背景 我们在项目上遇到一个需求,需要将组织机构数据(包含人员信息、部门信息、分部信息、人岗关系)生成的增量数据,实时同步到三方的系统中,三方要求,只需要增量数据即可。 那么基于ecology系统&a…...
FVM安装及配置
一、下载fvm 包 git:Release fvm 3.1.7 leoafarias/fvm GitHub 解压到本地文件夹,然后添加环境变量 管理员模式打开cmd,查看是否成功 fvm --version 二、安装Dart SDK 下载Dart SDK:Dart for Windows 三、安装GIT 四、指定…...
[Git][认识Git]详细讲解
目录 1.什么是仓库?2.认识工作区、暂存区、版本库3.认识 .git1.index2.HEAD && master3.objects4.总结 1.什么是仓库? 仓库:进⾏版本控制的⼀个⽂件⽬录 2.认识工作区、暂存区、版本库 工作区:在电脑上写代码或⽂件的⽬录…...
Win11系统Docker部署Blazor程序
1. 开发环境 Windows 11 家庭版,默认支持WSL2 2. Docker安装 安装Docker Desktop需要启用Win11的Linux子系统和虚拟机。以管理员身份运行命令行程序,执行如下命令: 启用适用于 Linux 的 Windows 子系统 dism.exe /online /enable-featur…...
C语言自定义类型结构体与位段超详解
文章目录 1. 结构体类型的声明1. 1 结构体声明1. 2 结构体变量的创建和初始化1. 3 结构体的特殊声明1. 3 结构体的自引用 2. 结构体内存对齐2. 1 对齐规则2. 2 为什么存在内存对齐2. 3 修改默认对齐数 3. 结构体传参4. 结构体实现位段4. 1 什么是位段4. 2 位段成员的内存分配4.…...
JS中关于预编译的【关键知识点】总结
在JavaScript中,预编译(hoisting)是指在代码执行之前,JavaScript引擎会首先对代码进行扫描,将所有的变量声明和函数声明提升到代码的最顶部。这一过程使得我们在代码中可以在声明之前使用变量和函数。理解预编译对于深…...
Elasticsearch 映射(mapping)
概念 在 Elasticsearch 中,映射(Mapping)定义了索引中字段的类型和属性。它是索引数据结构的基础,类似于传统数据库中的表结构定义。映射不仅定义了字段的类型(如 text、keyword、integer 等)…...
开放式耳机更适合运动的时候使用?开放式耳机推荐指南
开放式耳机确实非常适合运动时使用,原因主要有以下几点。 首先,保持对外界的感知是很重要的一点。在运动的时候,我们需要听到周围的环境声音,比如车辆的行驶声、行人的呼喊等,以便及时做出反应,保证自身安全…...
食堂窗口自助点餐小程序的设计
管理员账户功能包括:系统首页,个人中心,用户管理,商家管理,店铺信息管理,菜品分类管理,菜品信息管理,订单管理,系统管理 微信端账号功能包括:系统首页&#…...
请说出路由传参和获取参数的三种方式
在Vue.js中使用Vue Router进行路由管理时,传递和获取参数是常见的需求。这里介绍三种主要的路由传参和获取参数的方式: 1. 通过URL的查询参数(Query Parameters) 传递参数: 当你需要传递一些非敏感数据(…...
精准防控,高效管理:AI智能分析网关V4区域未停留检测算法的介绍及应用
一、区域未停留AI检测算法概述 随着人工智能和计算机视觉技术的飞速发展,区域未停留AI检测算法作为一种重要的视频分析技术,逐渐在各个领域得到广泛应用。该算法通过高效处理视频流数据,能够实时分析并判断目标对象是否在预设区域内有足够的…...
html+css練習:iconfont使用
1.網址地址:https://www.iconfont.cn/search/index 2.註冊登錄,將需要的圖標添加到購物車 3.下載代碼 4.下載后的代碼有一個html頁面,裡面有詳細的使用方式...
算法导论 总结索引 | 第五部分 第二十一章:用于不相交集合的数据结构
一些应用涉及 将n个不同的元素分成一组不相交的集合。寻找包含给定元素的唯一集合 和 合并两个集合 1、不相交集合的操作 1、一个不相交集合 数据结构 维持了 一个不相交动态集的集合 S {S_1, S_2,…, S_n}。用一个代表 来标识每个集合,它是这个集合的某个成员。…...
【单例设计模式】揭秘单例模式:从原理到实战的全方位解析(开发者必读)
文章目录 深入理解单例设计模式:原理、实现与最佳实践引言第一部分:设计模式简介第二部分:单例模式定义第三部分:单例模式的优点和缺点第四部分:单例模式的实现方式懒汉式非线程安全的实现线程安全的实现(双…...
VTK8.2.0编译(Qt 5.14.2+VS2017)
VTK8.2.0编译(Qt 5.14.2VS2017) 关于Qt和MSVC的安装,可以参考文章(QtMSVC2017)。 本篇VTK在QtMSVC的配置下的编译。VTK 以8.2.0为例。 一、环境变量的配置 我们打开电脑的环境变量,可以看到没有Qt相关的…...
武汉流星汇聚:亚马逊跨境电商龙头,市场份额稳固,服务品质卓越
在全球跨境电商的版图上,亚马逊无疑是一颗璀璨的明星,以其庞大的市场规模、卓越的用户体验和强大的品牌影响力,稳居行业龙头地位。即便在诸多新兴跨境平台竞相崛起的背景下,亚马逊依然以其独特的优势,保持着难以撼动的…...
挑战杯推荐项目
“人工智能”创意赛 - 智能艺术创作助手:借助大模型技术,开发能根据用户输入的主题、风格等要求,生成绘画、音乐、文学作品等多种形式艺术创作灵感或初稿的应用,帮助艺术家和创意爱好者激发创意、提高创作效率。 - 个性化梦境…...
RocketMQ延迟消息机制
两种延迟消息 RocketMQ中提供了两种延迟消息机制 指定固定的延迟级别 通过在Message中设定一个MessageDelayLevel参数,对应18个预设的延迟级别指定时间点的延迟级别 通过在Message中设定一个DeliverTimeMS指定一个Long类型表示的具体时间点。到了时间点后…...
Golang dig框架与GraphQL的完美结合
将 Go 的 Dig 依赖注入框架与 GraphQL 结合使用,可以显著提升应用程序的可维护性、可测试性以及灵活性。 Dig 是一个强大的依赖注入容器,能够帮助开发者更好地管理复杂的依赖关系,而 GraphQL 则是一种用于 API 的查询语言,能够提…...
OkHttp 中实现断点续传 demo
在 OkHttp 中实现断点续传主要通过以下步骤完成,核心是利用 HTTP 协议的 Range 请求头指定下载范围: 实现原理 Range 请求头:向服务器请求文件的特定字节范围(如 Range: bytes1024-) 本地文件记录:保存已…...
GitHub 趋势日报 (2025年06月08日)
📊 由 TrendForge 系统生成 | 🌐 https://trendforge.devlive.org/ 🌐 本日报中的项目描述已自动翻译为中文 📈 今日获星趋势图 今日获星趋势图 884 cognee 566 dify 414 HumanSystemOptimization 414 omni-tools 321 note-gen …...
涂鸦T5AI手搓语音、emoji、otto机器人从入门到实战
“🤖手搓TuyaAI语音指令 😍秒变表情包大师,让萌系Otto机器人🔥玩出智能新花样!开整!” 🤖 Otto机器人 → 直接点明主体 手搓TuyaAI语音 → 强调 自主编程/自定义 语音控制(TuyaAI…...
MySQL中【正则表达式】用法
MySQL 中正则表达式通过 REGEXP 或 RLIKE 操作符实现(两者等价),用于在 WHERE 子句中进行复杂的字符串模式匹配。以下是核心用法和示例: 一、基础语法 SELECT column_name FROM table_name WHERE column_name REGEXP pattern; …...
力扣-35.搜索插入位置
题目描述 给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。 请必须使用时间复杂度为 O(log n) 的算法。 class Solution {public int searchInsert(int[] nums, …...
SAP学习笔记 - 开发26 - 前端Fiori开发 OData V2 和 V4 的差异 (Deepseek整理)
上一章用到了V2 的概念,其实 Fiori当中还有 V4,咱们这一章来总结一下 V2 和 V4。 SAP学习笔记 - 开发25 - 前端Fiori开发 Remote OData Service(使用远端Odata服务),代理中间件(ui5-middleware-simpleproxy)-CSDN博客…...
Linux离线(zip方式)安装docker
目录 基础信息操作系统信息docker信息 安装实例安装步骤示例 遇到的问题问题1:修改默认工作路径启动失败问题2 找不到对应组 基础信息 操作系统信息 OS版本:CentOS 7 64位 内核版本:3.10.0 相关命令: uname -rcat /etc/os-rele…...
