Java线程:并发/并行区别、线程生命周期、乐观锁/悲观锁

article/2025/8/1 18:05:32

并发、并行

进程

  • 正在运行的程序(软件)就是一个独立的进程
  • 线程是属于进程的,一个进程中可以同时运行很多个线程
  • 进程中的多个线程其实是并发和并行执行的

并发

进程中的线程是由CPU负责调度执行的,但CPU能同时处理线程的数量有限,为了保证全部线程都能往前执行,CPU会轮询为系统的每个线程服务,由于CPU切换的速度很快,给我们的感觉这些线程在同时执行,这就是并发
在这里插入图片描述

eg:老师以很快的速度给班上的每个学生分别发糖

并行

同一个时刻上同时有多个线程在被CPU调度执行
在这里插入图片描述
多线程到底是怎么在执行的:并发和并行同时进行的

线程的生命周期

也就是线程从生到死的过程中,经历的各种状态及状态转换

Java线程的状态

Java总共定义了6种状态
6种状态都定义在Thread类的内部枚举类中

6种状态的相互转变

sleep不会释放锁,而wait会

在这里插入图片描述
在这里插入图片描述

乐观锁、悲观锁

悲观锁:

一上来就加锁,没有安全感。每次只能一个线程进入访问完毕后,再解锁。线程安全,性能较差

乐观锁:

一开始不上锁,认为是没有问题的,大家一起跑,等要出现线程安全问题的时候才开始控制。线程安全,性能较好

需求:1变量,100个线程,每个线程对其加100次

public class Test1 {public static void main(String[] args) {//需求:1变量,100个线程,每个线程对其加100次//任务只有一个,所以new一个就行Runnable target = new MyRunnable();//用于完成这个任务的线程有100个for (int i = 1; i <= 100; i++) {new Thread(target).start();}}
}
public class MyRunnable implements Runnable{private int count; //记录浏览人数@Overridepublic void run() {//每个线程+100次for (int i = 0; i < 100; i++) {System.out.println("count=====>"+(++count));}}
}

运行结果:
请添加图片描述
按理说应该是加到了10000,但是最终只加到了9999→出现了线程安全问题(多个线程访问同一个共享资源)

有时候也能加到10000,即有时候安全有时候不安全

比如两个线程都将10拽出去然后加1再放回去,导致了少加了一次

解决方法1:

悲观锁

对代码加锁使每次对count进行修改时加锁,而不是对方法加锁使某一个线程加满100次之后再让下一个线程进行加

public class MyRunnable implements Runnable{private int count; //记录浏览人数@Overridepublic void run() {//每个线程+100次for (int i = 0; i < 100; i++) {//Runnable对象只new了1份,故this就是代指本次任务对象即target对象System.out.println(this); //保险起见打印一下看看this是不是Runnable对象synchronized (this) {System.out.println("count=====>"+(++count));}}}
}

运行结果
请添加图片描述
请添加图片描述
与之前不同的是,现在count是一个一个加的,即打印出的count是有序的,且能加到10000了,线程安全了

解决方法2:

乐观锁

虽然代码出现了线程安全问题,但是最终的结果也是很接近我们想要的结果的,即只是偶尔发生了线程冲突

比较和交换算法CAS
整数修改的乐观锁

原子类实现

public class Test2 {public static void main(String[] args) {//需求:1变量,100个线程,每个线程对其加100次//任务只有一个,所以new一个就行Runnable target = new MyRunnable2();//用于完成这个任务的线程有100个for (int i = 1; i <= 100; i++) {new Thread(target).start();}}
}
public class MyRunnable2 implements Runnable{
//    private int count; //记录浏览人数// 整数修改的乐观锁:原子类实现的private AtomicInteger count = new AtomicInteger();@Overridepublic void run() {//每个线程+100次for (int i = 0; i < 100; i++) {//count.incrementAndGet()效果等价于++countSystem.out.println(Thread.currentThread().getName() + "count=====>" + count.incrementAndGet());}}
}

http://www.hkcw.cn/article/uoUXneuTrS.shtml

相关文章

等保测评-Mysql数据库测评篇

Mysql数据库测评 0x01 前言 "没有网络安全、就没有国家安全" 等保测评是什么&#xff1f; 等保测评&#xff08;网络安全等级保护测评&#xff09;是根据中国《网络安全法》及相关标准&#xff0c;对信息系统安全防护能力进行检测评估的法定流程。其核心依据《信…

mysql的Memory引擎的深入了解

目录 1、Memory引擎介绍 2、Memory内存结构 3、内存表的锁 4、持久化 5、优缺点 6、应用 前言 Memory 存储引擎 是 MySQL 中一种高性能但非持久化的存储方案&#xff0c;适合临时数据存储和缓存场景。其核心优势在于极快的读写速度&#xff0c;需注意数据丢失风险和内存占…

QNAP MEMOS 域名访问 SSL(Lucky)

注意&#xff1a;下述是通过ssh、docker-compose方式安装docker的&#xff0c;不是直接在container station中安装的哈&#xff01;&#xff01;&#xff01; 一、编辑docker-compose.yml文件 用“#”号标识的&#xff0c;在保存文件的时候建议去掉&#xff0c;不然有时候会出…

BioID技术在宿主-病原体相互作用领域的应用

细菌感染是全球公共卫生的重大威胁&#xff0c;而抗生素耐药性的提升使我们迫切需要深入了解宿主 -病原体相互作用。细菌病原体通过分泌效应蛋白&#xff0c;操纵宿主细胞以建立感染。这些效应蛋白通过与宿主蛋白相互作用&#xff0c;改变宿主细胞功能&#xff0c;但传统研究方…

解析楼宇自控系统:分布式结构的核心特点与优势展现

在建筑智能化发展的进程中&#xff0c;楼宇自控系统作为实现建筑高效运行与管理的关键&#xff0c;其系统结构的选择至关重要。传统的集中式楼宇自控系统在面对日益复杂的建筑环境和多样化的管理需求时&#xff0c;逐渐暴露出诸多弊端&#xff0c;如可靠性低、扩展性差、响应速…

SAP Business One:无锡哲讯科技助力中小企业数字化转型的智慧之选

数字化转型&#xff0c;中小企业的必经之路 在当今竞争激烈的商业环境中&#xff0c;数字化转型已不再是大型企业的专利&#xff0c;越来越多的中小企业开始寻求高效、灵活的管理系统来优化业务流程、提升运营效率。作为全球领先的企业管理软件&#xff0c;SAP Business One…

Python基于Django的校园打印预约系统(附源码,文档说明)

博主介绍&#xff1a;✌IT徐师兄、7年大厂程序员经历。全网粉丝15W、csdn博客专家、掘金/华为云//InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;&#x1f3…

身份证发给别人怎么加水印?赛文奥特曼身份证添加水印教程

我们经常需要使用身份证照片进行身份验证、资料提交等操作。然而&#xff0c;直接将身份证照片发送给他人或上传到网络存在一定的信息泄露风险。为了更好地保护个人隐私&#xff0c;我们可以使用 简鹿水印助手 这款工具&#xff0c;在身份证照片上添加专属水印&#xff0c;从而…

Express教程【002】:Express监听GET和POST请求

文章目录 2、监听post和get请求2.1 监听GET请求2.2 监听POST请求 2、监听post和get请求 创建02-app.js文件。 2.1 监听GET请求 1️⃣通过app.get()方法&#xff0c;可以监听客户端的GET请求&#xff0c;具体的语法格式如下&#xff1a; // 1、导入express const express req…

ESP32-C3 Vscode+ESP-IDF开发环境搭建 保姆级教程

1.背景 最近esp32的芯片很火&#xff0c;因为芯片自带了WIFI和BLE功能&#xff0c;是物联网项目开发的首选芯片&#xff0c;所以&#xff0c;我也想搞个简单的esp32芯片试试看。于是&#xff0c;我设计了一个简单的板子。如下 这块板子很简单&#xff0c;主要的电路来自于乐鑫…

深入 RAG(检索增强生成)系统架构:如何构建一个能查资料的大语言模型系统

&#x1f407;明明跟你说过&#xff1a;个人主页 &#x1f3c5;个人专栏&#xff1a;《深度探秘&#xff1a;AI界的007》 &#x1f3c5; &#x1f516;行路有良友&#xff0c;便是天堂&#x1f516; 目录 一、前言 1、LLM 的局限&#xff1a;模型知识“封闭” vs 现实知识…

VSCode+Cline 安装配置及使用说明

安装配置 打开VSCode&#xff0c;点击左侧Extension图标&#xff0c;在弹出页面中&#xff0c;检索Cline&#xff0c;选择Cline进行安装。 安装完毕&#xff0c;在左侧会出现一个图标&#xff0c;点击图标 选择【Use your own API key】&#xff0c;在出来的界面中选择大模型&…

【征求意见】四川省大数据发展研究会关于对《数据资源建设费用测算标准》团体标准征求意见的通知

四川省大数据发展研究会 关于对《数据资源建设费用测算标准》团体标准征求意见的通知 各有关单位&#xff1a; 由四川省大数据发展研究会归口、成都东契奇科技有限公司牵头编制的《数据资源建设费用测算标准》团体标准已形成征求意见稿&#xff0c;现公开征求意见。请于2025年…

下载即转化的商业密码:解析华为应用商店CPD广告的智能投放逻辑

在移动互联网流量红利见顶的背景下&#xff0c;华为应用市场凭借其终端生态优势正成为开发者获客的新蓝海。数据显示&#xff0c;2025年Q1华为应用商店全球分发量同比增长27%&#xff0c;其中CPD广告因其"下载才付费"的精准特性&#xff0c;已成为金融、游戏、工具类…

Electron-vite【实战】MD 编辑器 -- 文件列表(含右键快捷菜单,重命名文件,删除本地文件,打开本地目录等)

最终效果 页面 src/renderer/src/App.vue <div class"dirPanel"><div class"panelTitle">文件列表</div><div class"searchFileBox"><Icon class"searchFileInputIcon" icon"material-symbols-light:…

【数据库】并发控制

并发控制 在数据库系统&#xff0c;经常需要多个用户同时使用。同一时间并发的事务可达数百个&#xff0c;这就是并发引入的必要性。 常见的并发系统有三种&#xff1a; 串行事务执行&#xff08;X&#xff09;&#xff0c;每个时刻只有一个事务运行&#xff0c;不能充分利用…

Golang持续集成与自动化测试和部署

概述 Golang是一门性能优异的静态类型语言&#xff0c;但因其奇快的编译速度&#xff0c;结合DevOps, 使得它也非常适合快速开发和迭代。 本文讲述如何使用Golang, 进行持续集成与自动化测试和部署。主要使用了以下相关技术&#xff1a; dep&#xff1a; 进行包的依赖管理gin…

Google car key:安全、便捷的汽车解锁新选择

有了兼容的汽车和 Android 手机&#xff0c;Google car key可让您将Android 手机用作车钥匙。您可以通过兼容的 Android 手机锁定、解锁、启动汽车并执行更多功能。但是&#xff0c;Google car key安全吗&#xff1f;它是如何工作的&#xff1f;如果我的手机电池没电了怎么办&a…

QT开发技术【QTableView分页实现】

一、引言 在开发桌面应用程序时&#xff0c;当需要展示大量数据到表格中&#xff0c;一次性加载所有数据可能会导致界面卡顿、响应缓慢&#xff0c;甚至内存溢出。QTableView 是 Qt 框架中用于展示表格数据的强大组件&#xff0c;结合 QAbstractTableModel 可以实现数据的分页…

新增Vulkan支持|UWA Gears V1.1.0

UWA Gears 是UWA最新发布的无SDK性能分析工具。针对移动平台&#xff0c;提供了实时监测和截帧分析功能&#xff0c;帮助您精准定位性能热点&#xff0c;提升应用的整体表现。 本次版本更新主要是Frame Capture模式新增对Vulkan项目的支持&#xff0c;进一步满足使用Vulkan开发…