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

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);}
}

在这个例子中,两个线程分别持有了KeyAKeyB的锁,并试图获取对方的锁。由于它们都无法释放自己持有的锁,因此陷入了死锁。

第三章:解锁同步的智慧

要避免死锁的诅咒,我们需要掌握更高级的同步技巧。在Java中,java.util.concurrent包提供了多种工具,如ReentrantLockSemaphoreCondition,它们提供了比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();}}
}

在这个例子中,信号量限制了同时访问资源的线程数量,有效地避免了资源争抢。

http://www.lryc.cn/news/413422.html

相关文章:

  • CoderGuide
  • 链式二叉树
  • PHP高校迎新系统-计算机毕业设计源码08468
  • 泛微开发修炼之旅--41Ecology基于触发器实现增量数据同步(人员、部门、岗位、人员关系表、人岗关系表)
  • FVM安装及配置
  • [Git][认识Git]详细讲解
  • Win11系统Docker部署Blazor程序
  • C语言自定义类型结构体与位段超详解
  • JS中关于预编译的【关键知识点】总结
  • Elasticsearch 映射(mapping)
  • 开放式耳机更适合运动的时候使用?开放式耳机推荐指南
  • 食堂窗口自助点餐小程序的设计
  • 请说出路由传参和获取参数的三种方式
  • 精准防控,高效管理:AI智能分析网关V4区域未停留检测算法的介绍及应用
  • html+css練習:iconfont使用
  • 算法导论 总结索引 | 第五部分 第二十一章:用于不相交集合的数据结构
  • 【单例设计模式】揭秘单例模式:从原理到实战的全方位解析(开发者必读)
  • VTK8.2.0编译(Qt 5.14.2+VS2017)
  • 武汉流星汇聚:亚马逊跨境电商龙头,市场份额稳固,服务品质卓越
  • 我出一道面试题,看看你能拿 3k 还是 30k!
  • opecv c++计算图像的曲率
  • 鸿蒙 IM 即时通讯开发实践,融云 IM HarmonyOS NEXT 版
  • 【全国大学生电子设计竞赛】2022年D题
  • 【优秀python案例】基于python爬虫的深圳房价数据分析与可视化实现
  • vscode安装与配置本地c/c++编译调试环境
  • PCIe学习笔记(15)
  • Rust中的特殊类型所占的内存大小
  • 【深度学习】变分自编码器 VAE,什么是变分?(1)
  • 宏编程:C++宏、Rust宏和Lisp宏比较
  • ChatGPT协助撰写研究论文的11种方法【全集】