高薪程序员必修课-java并发编程的bug源头

前言

        Java并发编程虽然强大,但也容易引发复杂的bug。并发编程的bug主要源自以下几个方面:竞态条件、死锁、内存可见性问题和线程饥饿。了解这些bug的源头及其原理,可以帮助开发者避免和解决这些问题。以下是详细的讲解和相应的示例。

1. 竞态条件(Race Condition)

原理

竞态条件发生在多个线程同时访问和修改共享资源时,由于操作的交错顺序不同,导致程序的行为和结果不可预测。具体表现为多个线程在没有适当同步的情况下访问和修改同一变量。

示例

下面是一个竞态条件的示例,演示多个线程同时修改共享变量 counter 的问题。

public class RaceConditionExample {private static int counter = 0;public static void main(String[] args) {Runnable task = () -> {for (int i = 0; i < 1000; i++) {counter++;}};Thread thread1 = new Thread(task);Thread thread2 = new Thread(task);thread1.start();thread2.start();try {thread1.join();thread2.join();} catch (InterruptedException e) {e.printStackTrace();}System.out.println("Final counter value: " + counter);  // 预期结果应为2000}
}

2. 死锁(Deadlock)

原理

死锁是指两个或多个线程相互等待对方持有的资源,导致所有线程都无法继续执行。死锁通常发生在多线程程序中使用多个锁时,锁获取的顺序不一致导致循环等待。

示例

下面是一个简单的死锁示例,两个线程尝试获取相同的锁,但顺序不同,导致死锁。

public class DeadlockExample {private static final Object lock1 = new Object();private static final Object lock2 = new Object();public static void main(String[] args) {Thread thread1 = new Thread(() -> {synchronized (lock1) {System.out.println("Thread 1: Holding lock 1...");try { Thread.sleep(100); } catch (InterruptedException e) {}System.out.println("Thread 1: Waiting for lock 2...");synchronized (lock2) {System.out.println("Thread 1: Holding lock 1 & 2...");}}});Thread thread2 = new Thread(() -> {synchronized (lock2) {System.out.println("Thread 2: Holding lock 2...");try { Thread.sleep(100); } catch (InterruptedException e) {}System.out.println("Thread 2: Waiting for lock 1...");synchronized (lock1) {System.out.println("Thread 2: Holding lock 1 & 2...");}}});thread1.start();thread2.start();}
}

3. 内存可见性问题(Memory Visibility Issues)

原理

内存可见性问题指的是一个线程对共享变量的修改,另一个线程可能看不到。Java内存模型(JMM)允许线程将变量缓存到寄存器或CPU缓存中,而不是立即写入主内存。这会导致不同线程看到的变量值不一致。

示例

下面是一个内存可见性问题的示例,展示了一个线程对变量 running 的修改,另一个线程可能看不到。

public class MemoryVisibilityExample {private static boolean running = true;public static void main(String[] args) {Thread worker = new Thread(() -> {while (running) {// Busy-wait loop}System.out.println("Worker thread stopped.");});worker.start();try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}running = false;System.out.println("Main thread set running to false.");}
}

4. 线程饥饿(Thread Starvation)

原理

线程饥饿发生在某些线程长期得不到执行机会,通常是因为高优先级线程不断占用CPU时间,低优先级线程无法获取CPU资源。导致某些线程长期处于等待状态。

示例

下面是一个线程饥饿的示例,展示了低优先级线程可能永远得不到执行机会。

public class ThreadStarvationExample {public static void main(String[] args) {Thread highPriorityThread = new Thread(() -> {while (true) {// High priority task}});highPriorityThread.setPriority(Thread.MAX_PRIORITY);Thread lowPriorityThread = new Thread(() -> {while (true) {System.out.println("Low priority thread running...");}});lowPriorityThread.setPriority(Thread.MIN_PRIORITY);highPriorityThread.start();lowPriorityThread.start();}
}

总结

竞态条件
  • 原理:多个线程同时访问和修改共享资源。
  • 示例:多个线程同时增加共享变量。
死锁
  • 原理:两个或多个线程相互等待对方持有的资源。
  • 示例:线程1持有锁1等待锁2,线程2持有锁2等待锁1。
内存可见性问题
  • 原理:一个线程对共享变量的修改,另一个线程可能看不到。
  • 示例:一个线程修改变量 running,另一个线程看不到变化。
线程饥饿
  • 原理:某些线程长期得不到执行机会。
  • 示例:高优先级线程不断占用CPU时间,低优先级线程无法获取CPU资源。

理解并发编程中的这些bug源头和原理,并采用适当的同步机制(如 synchronizedLockvolatile)以及并发工具(如 CountDownLatchSemaphoreConcurrentHashMap),可以有效避免和解决这些问题。

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

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

相关文章

SpringBoot 中的参数校验:构建健壮应用的基石

前言 在开发Web应用时&#xff0c;处理用户输入是不可避免的一环。然而&#xff0c;用户输入往往充满不确定性&#xff0c;可能是格式不正确、类型不匹配&#xff0c;甚至包含恶意内容。为了确保应用的稳定性和安全性&#xff0c;对输入参数进行有效校验显得尤为重要。Spring …

【触想智能】工业平板电脑在新能源领域上的应用分析

工业平板电脑是一种具有高性能和稳定性的计算机设备&#xff0c;适用于在恶劣环境下进行数据采集、运营管理和现场操作。 随着新能源技术的快速发展&#xff0c;工业平板电脑不断地得到应用&#xff0c;并且已成为新能源领域中的重要工具之一。本文将从四个方面探讨工业平板电脑…

第32讲:K8S集群与Cephfs文件系统集成

文章目录 1.在K8S环境下RBD与Cephfs的使用对比2.Cephfs环境介绍3.在Ceph集群中为K8S创建单独Cephfs文件系统和认证用户3.1.创建一个K8S使用的Cephfs文件系统3.2.将创建的Cephfs文件系统挂载到本地路径3.3.创建K8S连接Ceph集群使用的认证用户 4.K8S PV存储卷使用Cephfs文件系统4…

WSO2 products 文件上传漏洞(CVE-2022-29464)

前言 CVE-2022-29464 是一个影响多个 WSO2 产品的严重远程代码执行&#xff08;RCE&#xff09;漏洞。这些产品包括 WSO2 API Manager、WSO2 Identity Server 和 WSO2 Enterprise Integrator 等。由于用户输入验证不当&#xff0c;该漏洞允许未经身份验证的攻击者在服务器上上…

代码随想录算法训练营第九天|151.翻转字符串里的单词、右旋字符串、28. 实现 strStr()、459.重复的子字符串

打卡Day9 1.151.翻转字符串里的单词2.右旋字符串3.28. 实现 strStr()4.459.重复的子字符串 1.151.翻转字符串里的单词 题目链接&#xff1a;翻转字符串里的单词 文档讲解&#xff1a; 代码随想录 思路&#xff1a;首先&#xff0c;移除多余的空格&#xff1b;然后&#xff0c…

TensorRT学习(二)TensorRT使用教程(Python版)

本文适合快速了解TensorRT使用的整体流程,具体细节还是建议参考TensorRT的官方文档。 加速原理: 加速原理比较复杂,它将会根据显卡来优化算子,以起到加速作用(如下图所示)。简单的来说,就是类似于你出一个公式1+1+1,而你的显卡支持乘法,直接给你把这个公式优化成了1*…

论文调研_物联网漏洞检测综述

A Review of IoT Firmware Vulnerabilities and Auditing Techniques 研究背景&#xff1a;物联网设备在工业、消费类等各个领域得到了广泛应用&#xff0c;实现了更高的自动化和生产率。然而&#xff0c;这些连网设备的高度依赖也带来了一系列网络安全威胁&#xff0c;特别是…

生成式AI赋能金融信贷:减少信用评分偏差

信用评分在确定谁获得信贷以及以何种条件获得信贷方面发挥着关键作用。然而&#xff0c;尽管这一点很重要&#xff0c;但传统的信用评分系统长期以来一直受到一系列关键问题的困扰——从偏见和歧视&#xff0c;到有限的数据考虑和可扩展性挑战。例如&#xff0c;一项针对美国贷…

【代码随想录】【算法训练营】【第56天】 [卡码98]所有可达路径

前言 思路及算法思维&#xff0c;指路 代码随想录。 题目来自 卡码网。 day 56&#xff0c;周二&#xff0c;继续ding~ 题目详情 [卡码98] 所有可达路径 题目描述 卡码98 所有可达路径 解题思路 前提&#xff1a; 思路&#xff1a; 重点&#xff1a; 代码实现 C语言…

你了解人工智能吗?

前言 人工智能&#xff08;Artificial Intelligence&#xff0c;AI&#xff09;是计算机科学的一个重要分支&#xff0c;致力于开发能够执行通常需要人类智能的任务的系统。本文将从历史发展、关键技术、应用领域以及未来挑战等方面&#xff0c;深入探讨人工智能的相关内容。 …

【JPCS出版,PSESG 2024,8月16-18】2024年电力系统工程与智能电网国际学术会议

2024年电力系统工程与智能电网国际学术会议(PSESG 2024)于2024年8月16-18日在中国北京隆重召开。 会议旨在为从事“电力系统工程”、“智能电网”、“储能技术”等领域的专家学者、工程技术人员、研发人员提供一个共享科研成果和前沿技术&#xff0c;了解学术发展趋势&#xf…

GPT-5即将登场:AI赋能下的未来工作与日常生活新图景

随着OpenAI首席技术官米拉穆拉蒂在近期采访中的明确表态&#xff0c;GPT-5的发布已不再是遥不可及的梦想&#xff0c;而是即将在一年半后与我们见面的现实。这一消息无疑在科技界乃至全社会引发了广泛关注和热烈讨论。从GPT-4到GPT-5的飞跃&#xff0c;被形容为从高中生到博士生…

SpringBoot之内容协商

现象演示 假设有一个需求是根据终端的不同&#xff0c;返回不同形式的数据&#xff0c;比如 PC 端需要以 HTML 格式返回数据&#xff0c;APP、小程序端需要以 JSON 格式返回数据。这时我们是 coding 几个相似的接口&#xff1f;还是在一个接口里面做复杂判断处理&#xff1f;两…

SQL执行慢排查以及优化思路

数据库服务器的优化步骤 当我们遇到数据库调优问题的时候&#xff0c;该如何思考呢&#xff1f;我把思考的流程整理成了下面这张图。 整个流程划分成了观察&#xff08;Show status&#xff09;和行动&#xff08;Action&#xff09;两个部分。字母 S 的部分代表观察&#xf…

LSH算法:高效相似性搜索的原理与Python实现I

局部敏感哈希&#xff08;LSH&#xff09;技术是快速近似最近邻&#xff08;ANN&#xff09;搜索中的一个关键方法&#xff0c;广泛应用于实现高效且准确的相似性搜索。这项技术对于许多全球知名的大型科技公司来说是不可或缺的&#xff0c;包括谷歌、Netflix、亚马逊、Spotify…

分文件编译(简单学生系统)

定义学生基本信息 ①输出所有学生信息 ②删除某个学生后&#xff0c;输出所有学生信息 ③修改某个学生信息后&#xff0c;输出所有学生信息 ④查找某个学生的信息 main.c #include"k11*.h" int main(int argc, const char *argv[]) {struct student p[4]{{"…

Echarts-柱状图

1.案例1 1.1代码 option = {textStyle: {color: #fff // 标题文字颜色为白色},tooltip: {trigger: axis,axisPointer: {type: shadow,},},legend: {textStyle: {color: white}},grid: {top: 15%,left: 4%,right: 4%,bottom: 7%,containLabel: true},xAxis:{type: category,da…

仿全民飞机大战射击网页游戏源码

仿全民飞机大战设计网页游戏源码&#xff0c;画质精美的飞机大战手机端游戏源码 微信扫一扫免费下载源码

Mac|install vue

安装Node&#xff1a;Node.js — Download Node.js 选择系统为mac&#xff0c;安装步骤在终端输入 &#xff08;放文字版在这里&#xff5e;方便复制&#xff09; # installs nvm (Node Version Manager) curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/ins…

78.Vue 3 重用性模态框组件

模态框是大多数 Web 应用程序中的基本构建块。虽然最初实现起来可能看起来有点棘手&#xff0c;但实际上&#xff0c;使用 Vue 和一些 Flexbox 技巧&#xff0c;这不仅可行&#xff0c;而且非常简单。 让我们一起实现一个基础的模态框组件。 架构如下&#xff1a; AppModal.vue…