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

Java并发基础理论

Java并发基础理论

进程与线程

进程

​ 进程是程序的一次执行过程,是系统运行程序的基本单位,因为进程是动态的。系统运行一个程序就是一个进程从创建运行到消亡的过程。

​ 我们启动main方法其实就是启动了一个JVM进程,而main方法所在的线程就是这个线程中的一个进程也称呼为主进程。

线程

​ 线程与进程相似,但是线程是一个比进程更小的执行单位。一个进程可以在执行过程中产生多个线程,线程是多个线程层贡献进程的堆和方法区资源,但是每个线程都拥有自己的程序计数器、jvm stack和本地方法栈,一个系统产生一个线程或者在各个线程之间切换工作负担要比进程小很多。

线程与进程的关系

​ 线程是进程划分的更小的运行单位,线程和进程最大的不同在于是,进程是独立的,而各线程则不一定他们会贡献一些资源,像堆和元空间。线程执行开销小,但是不利于资源的管理和保护,而进程正好相反。

程序计数器为什么是私有的

​ 程序计数器主要有2个作用

  1. 字节码解器起通过改变程序计数器一次读取指令,从而实现代码的流程的控制,如:顺序、选择、循环、异常处理。

  2. 在多线程的情况下,程序计数器用于记录当前线程执行的位置。从而当线程被切换回来的时候能够知道该线程上次执行到哪里了。

    例如当一个线程因为实践篇货其他高优先级的线程来了,系统就会暂停线程的执行,并将控制权转移到另一个线程,当这个线程在被调用的时候就会根据程序计数器的值告诉他上次执行到哪里了。

    ​ 如果执行的是本natvie方法,那么程序计数器记录的就是undefined地址。

    所以程序私有主要为了线程切换后能后恢复争取的位置执行

jvm stack和本地方法栈为什么是私有的

​ jvm stack:每个java方法在执行之前会创建一个栈桢用于存储变量标、操作数栈、常量池饮用等信息。才能够方法调用直至执行完毕的过程,就对应一个栈桢在jvm stack一个入栈和出栈的过程。

​ 本地方法栈:和虚拟机所发挥的作用非常类似,区别是:虚拟机栈为执行java方法(字节码)服务,而本地方法栈则为虚拟机使用到的本地方法服务。在HotSpot虚拟机中和java虚拟机合二为一。

堆和方法区

​ 堆和方法区是所有线程共享的资源,其中堆是进程最大的一块内存,用来存储新创建的对象。

​ 方法区主要用于存放已被夹在的类信息、常量、静态变量、即使编译器后的代码等数据。

并发和并行

​ 并发:两个及两个以上的作业在同一时间段内执行。

​ 并行:两个及两个以上的作业在同一时刻执行。

同步和异步的区别

​ 同步:发出一个调用之后,在没有得到结果之前,该调用就不可以返回,一直等待。

​ 异步:调用在发出之后,不用等待返回结果,该调用直接return;

为什么使用多线程

从计算机底层角度来说

​ 线程可以比作是轻量级的线程,是程序执行的最小单位,线程间的切换和调度的成本远远小于进程。另外多核CPU时代意味着多个线程可以运行,这减少了线程上下文切换的开销。

从互联网发展趋势来说

​ 现在的系统并发要求很大, 而多线程并发编程就是高并发系统的基础,这就可以利用好多线程机制可以大大提高系统整体的并发能力和性能。

使用多线程可能带来什么问题

​ 并发编程的目的就是为了提高程序的执行效率提高程序的速度,可能带来的问题有内存泄漏、死锁、线程不安全等等。

如何理解线程安全和不安全

线程安全和不安群啊是对同一份数据的访问是否能达到一致性和正确性

线程的生命周期

Java线程的生命周期有6种状态,操作系统层面来看有7种

new:初始状态,线程创建出来,没有调用start方法

READY:可运行状态(在操作系统角度来看)

runnable:运行状态,线程调用了start等待运行的状态

blocked:堵塞状态,需要等待锁释放

waiting:等待状态,表示线程需要等待其他线程做出一些特定的动作。

time_waiting:超时等待状态,等已在指定的时间后自行返回而不是axingwaiting那样一直等待

terminated:终止状态,表示线程已经运行完毕。

线程的状态是随着代码的执行在不同状态之间切换的。

​ 当我们创建线程它属于new状态, 调用了start方法就是ready(可运行状态),可运行状态的线程获得了CPU时间片(timeslice)后就处于runnning(运行)状态,当线程执行了wait方法就会进入waiting状态,进入等待状态需要其他线程通知才能返回到运行状态。如果通过sleep和wait(long mullis)方法可以将线程状态编程timed——waiting状态,当超时时间结束就会返回runnning状态。当一个线程进入synchhronized的时候如果该方法块已经被其他线程持有锁那么就会进入堵塞状态,直到它获取到锁,当线程调用wait方法后,它会释放持久的锁并且进入等待状态,当其他线程notity这个这个线程,被唤醒的线程会尝试重新获取锁这个时候就会进入堵塞blocked状态。当鲜橙国之ing晚run方法之后就会进入terminated终止状态

线程的上下文切换

线程在执行过程中会有自己的运行条件和状态(也称上下文),比如上文所说过的程序计数器,栈桢信息等。

​ 当我们调用sleep和wait主动让出cpu的时候

​ cpu时间片用完,因为操作系统要防止一个线程货进程长时间占用CPU导致其他线程或者进程饿死。

​ 调用了堵塞类型的系统中断,比如请求IO,线程被堵塞

​ 被终止或结束运行。

前三者上下文切换的时候会保留信息线程的上下文信息,留着下一次使用的时候恢复现场。

什么是死锁,如何避免死锁

线程死锁就是多个线程被堵塞,他们中的一个活着全部都在等待某个资源释放,由于线程被无限期的堵塞,因此程序不可以正常结束。

public class DeadLockDemo {private static Object resource1 = new Object();//资源 1private static Object resource2 = new Object();//资源 2public static void main(String[] args) {new Thread(() -> {synchronized (resource1) {System.out.println(Thread.currentThread() + "get resource1");try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread() + "waiting get resource2");synchronized (resource2) {System.out.println(Thread.currentThread() + "get resource2");}}}, "线程 1").start();new Thread(() -> {synchronized (resource2) {System.out.println(Thread.currentThread() + "get resource2");try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread() + "waiting get resource1");synchronized (resource1) {System.out.println(Thread.currentThread() + "get resource1");}}}, "线程 2").start();}
}

如何预防死锁

​ 我们可以通过一次性申请所有资源和占用部分线程资源的线程如果去申请其他线程如果申请不到就主动释放它占用的资源和按照一定的顺序去申请资源,释放的时候就反序列释放

如果避免死锁

​ 避免死锁就是在资源分配的时候借助算法如银行家算法对资源进行评估、使线程进入安全状态,如P1 P2 P3

new Thread(() -> {synchronized (resource1) {System.out.println(Thread.currentThread() + "get resource1");try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread() + "waiting get resource2");synchronized (resource2) {System.out.println(Thread.currentThread() + "get resource2");}}}, "线程 2").start();

sleep方法和wait方法的区别

他们的共同点都可以暂停线程的执行。

sleep方法没有释放锁,而wait释放了锁

wait通常用于线程间的交互 or 通信,sleep通常用来暂停执行。

wait方法被调用了不会自动苏醒,需要别的线程notify或者notifuAll,sleep方法执行完毕后会自动苏醒,但是我们也可以给wait方法传递指定的时间,在指定的时间后也会苏醒。

sleep是thread类的静态本地方法,wait则是Object类的本地方法。

为什么wait方法不定义在Thread

wait方法是获得对象锁的线程实现等待,会自动释放当前线程占用的对象锁,每个对象都拥有对象锁,释放锁让让对象锁进入waiting状态,自然就是要操作对象的Object而非Thead

为什么sleep不定义在Object中

因为sleep就是让当前线程暂停执行,不涉及对象类,也不需要获得对象锁。

可以直接调用Thread类的run方法执行吗

答案是可以的,如果这么做只会当做一个main线程下的普通方法去执行,并不会在某个线程中执行,因为new Thread的时候线程就进入了new状态,调用start方法就进入了就绪状态,分配到时间片就开始运行,start会执行线程会执行相应的准备工作,然后自动执行run()方法,这就是真正的多线程工作。

相关文章:

Java并发基础理论

Java并发基础理论 进程与线程 进程 ​ 进程是程序的一次执行过程,是系统运行程序的基本单位,因为进程是动态的。系统运行一个程序就是一个进程从创建运行到消亡的过程。 ​ 我们启动main方法其实就是启动了一个JVM进程,而main方法所在的线…...

ubuntu22.04静态ip设置(桥接模式、only-host+NAT模式)

在创建一台虚拟机后,默认的方式往往是通过DHCP动态的进行分配,DHCP服务器会告知创建的虚拟机分配到的ip地址,网关地址等信息。所以在创建好虚拟机之后,这些信息都不需要我们来配置,我们直接用就好了。 但是&#xff0…...

深度模型中的正则化、梯度裁剪、偏置初始化操作

最近调试代码,发现怎么调试都不行,就想着用一些优化方式,然后又不是很清楚这些优化方式的具体细节,然后就学习了一下,这里记录下来,方便以后查阅。 深度模型中的正则化、梯度裁剪、偏置初始化操作 正则化常…...

设计模式之装饰模式

定义 装饰模式指的是在不必改变原类文件和使用继承的情况下,动态地扩展一个对象的功能。它是通过创建一个包装对象,也就是装饰来包裹真实的对象。 模式特点 (1) 装饰对象和真实对象有相同的接口。这样客户端对象就能以和真实对…...

华为OD机试真题 Java 实现【最佳对手】【2023Q1 200分】

一、题目描述 游戏里面,队伍通过匹配实力相近的对手进行对战。但是如果匹配的队伍实力相差太大,对于双方游戏体验都不会太好。 给定 n 个队伍的实力值,对其进行两两实力匹配,两支队伍实例差距在允许的最大差距 d内,则可以匹配。 要求在匹配队伍最多的情况下匹配出的各组…...

IOS证书制作教程

IOS证书制作教程 点击苹果证书 按钮 点击新增 输入证书密码,名称 这个密码不是账号密码,而是一个保护证书的密码,是p12文件的密码,此密码设置后没有其他地方可以找到,忘记了只能删除证书重新制作,所以请务…...

【人工智能】蚁群算法(密恐勿入)

蚁群算法(密恐勿入) 蚁群算法--给你一个感性认识 蚁群算法(密恐勿入)1. 算法简介1.1 基本原理1.1.1 模拟蚂蚁在简单地形,寻找食物1.1.2 模拟蚂蚁在复杂地形,找到食物1.2 算法应用 2. 算法解析3.算法应用——…...

VONR排查指导分享

不能注册或呼叫到SIP服务器端30秒挂断呼叫的黄金法则咬线或摘机状态单通或无语音收到400 bad request收到413,513 Request Entity Too Large或Message Too Large消息收到408, 480或者487 消息483 - Too Many Hops488 – Not Acceptable Here语音质量和思…...

Daftart.ai:人工智能专辑封面生成器

前言 Daft Art AI是一款使用人工智能技术来帮助您制作专辑封面的软件,它可以让您在几分钟内,用简单的编辑器和精选的美学风格,为您的专辑或歌曲创建出惊艳的高质量的艺术品。Daft Art AI有以下几个特点:简单易用:您只…...

ZigBee案例笔记 - 定时器

文章目录 1.片内外设I/O2.定时器简介3.定时器1寄存器4.定时器1操作自由运行模式模模式正计数/倒计数模式 5.16位计数器定时器1控制LED 示例 6.定时器3概述自由运行模式倒计数模式模模式正/倒计数模式 7.定时器3寄存器定时器3控制LED闪烁 1.片内外设I/O 定时器这样的片内外设也…...

GE H201TI 全系统自检和自诊断

Hydran 201Ti是一个小型在线预警发射器。它永久安装在变压器上,将为工作人员提供各种故障气体复合值的单一ppm读数,以提醒他们潜在的问题。 可以下载该值,并且可以将警报设置在预定水平,以提醒人员并能够监控发展中的故障状况。 …...

这个屏幕录制太好用了!

哈喽,大家好!今天给各位小伙伴测试了一屏幕录制的小工具——ApowerREC。它是一款专业同步录制屏幕画面及声音的录屏软件。界面简洁,操作简单,支持实时编辑屏幕录像、创建计划任务、录制摄像头高清视频等功能。废话不多说&#xff…...

初识redis【redis的安装使用与卸载】

一.redis的概念 Redis(Remote Dictionary Server ),即远程字典服务,是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。在redis官网中对redis的描述是这样的&#…...

接口测试总结及其用例设计方法整理,希望可以帮到你

目录 接口测试的总结文档 第一部分: 第二部分: 接口测试用例设计 接口测试的总结文档 第一部分:主要从问题出发,引入接口测试的相关内容并与前端测试进行简单对比,总结两者之前的区别与联系。但该部分只交代了怎么做…...

基于FPGA的多功能数字钟的设计

摘要 数字钟是采用数字电路实现对时、分、秒数字显示的计时装置,是人们日常 生活中不可少的必需品。本文介绍了应用FPGA芯片设计多功能数字钟的•种方 案,并讨讨论了有关使用FPGA芯片和VHDL语言实现数字钟设计的技术问题。 关键词数字钟、分频器、译码器、计数器、校时电路、…...

第四十二天学习记录:C语言进阶:笔试题整理Ⅲ

问:解释一下int(*a[20])(int)是什么? ChatAI答: int (*a[20])(int) 是一个数组,该数组中每个元素都是一个指向函数的指针,该函数具有一个int类型的参数,并返回一个int类型的值。 具体来说,a是一…...

GLSL 代码规范

文件 文件顶点,片段,几何和计算着色器文件应该分别有 _vert, _frag, geom 和 _comp 后缀(例如: eevee_film_fragg.glsl)。Shader文件名必须是唯一的,并且必须以它们所属的模块作为前缀(例如: workbench_material_lib.glsl eevee_film_lib.glsl)。一个 shader 文件必须包含且…...

红黑树封装map和set

文章目录 红黑树封装map和set1. 改良红黑树1.1 改良后的节点1.2 改良后的类分别添加仿函数代码 3. 封装map和set3.1 set3.2 map 3. 迭代器3.1 begin 和 end3.2 operator()和operator--()3.3 const迭代器set的迭代器map的迭代器 4. map的operator[]的重载5. 完整代码实现5.1 RBT…...

python序列

在Python中,序列类型包括字符串、列表、元组、集合和字典,这些序列支持以下几种通用的操作,但比较特殊的是,集合和字典不支持索引、切片、相加和相乘操作。 字符串也是一种常见的序列,它也可以直接通过索引访问字符串内…...

LeetCode35. 搜索插入位置(二分法入门)

写在前面: 题目链接:LeetCode35. 搜索插入位置 编程语言:C 题目难度:简单 一、题目描述 给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会…...

Java 语言特性(面试系列2)

一、SQL 基础 1. 复杂查询 (1)连接查询(JOIN) 内连接(INNER JOIN):返回两表匹配的记录。 SELECT e.name, d.dept_name FROM employees e INNER JOIN departments d ON e.dept_id d.dept_id; 左…...

uniapp微信小程序视频实时流+pc端预览方案

方案类型技术实现是否免费优点缺点适用场景延迟范围开发复杂度​WebSocket图片帧​定时拍照Base64传输✅ 完全免费无需服务器 纯前端实现高延迟高流量 帧率极低个人demo测试 超低频监控500ms-2s⭐⭐​RTMP推流​TRTC/即构SDK推流❌ 付费方案 (部分有免费额度&#x…...

Rust 异步编程

Rust 异步编程 引言 Rust 是一种系统编程语言,以其高性能、安全性以及零成本抽象而著称。在多核处理器成为主流的今天,异步编程成为了一种提高应用性能、优化资源利用的有效手段。本文将深入探讨 Rust 异步编程的核心概念、常用库以及最佳实践。 异步编程基础 什么是异步…...

Java 二维码

Java 二维码 **技术&#xff1a;**谷歌 ZXing 实现 首先添加依赖 <!-- 二维码依赖 --><dependency><groupId>com.google.zxing</groupId><artifactId>core</artifactId><version>3.5.1</version></dependency><de…...

python报错No module named ‘tensorflow.keras‘

是由于不同版本的tensorflow下的keras所在的路径不同&#xff0c;结合所安装的tensorflow的目录结构修改from语句即可。 原语句&#xff1a; from tensorflow.keras.layers import Conv1D, MaxPooling1D, LSTM, Dense 修改后&#xff1a; from tensorflow.python.keras.lay…...

C#中的CLR属性、依赖属性与附加属性

CLR属性的主要特征 封装性&#xff1a; 隐藏字段的实现细节 提供对字段的受控访问 访问控制&#xff1a; 可单独设置get/set访问器的可见性 可创建只读或只写属性 计算属性&#xff1a; 可以在getter中执行计算逻辑 不需要直接对应一个字段 验证逻辑&#xff1a; 可以…...

Spring Security 认证流程——补充

一、认证流程概述 Spring Security 的认证流程基于 过滤器链&#xff08;Filter Chain&#xff09;&#xff0c;核心组件包括 UsernamePasswordAuthenticationFilter、AuthenticationManager、UserDetailsService 等。整个流程可分为以下步骤&#xff1a; 用户提交登录请求拦…...

如何配置一个sql server使得其它用户可以通过excel odbc获取数据

要让其他用户通过 Excel 使用 ODBC 连接到 SQL Server 获取数据&#xff0c;你需要完成以下配置步骤&#xff1a; ✅ 一、在 SQL Server 端配置&#xff08;服务器设置&#xff09; 1. 启用 TCP/IP 协议 打开 “SQL Server 配置管理器”。导航到&#xff1a;SQL Server 网络配…...

从物理机到云原生:全面解析计算虚拟化技术的演进与应用

前言&#xff1a;我的虚拟化技术探索之旅 我最早接触"虚拟机"的概念是从Java开始的——JVM&#xff08;Java Virtual Machine&#xff09;让"一次编写&#xff0c;到处运行"成为可能。这个软件层面的虚拟化让我着迷&#xff0c;但直到后来接触VMware和Doc…...

二维FDTD算法仿真

二维FDTD算法仿真&#xff0c;并带完全匹配层&#xff0c;输入波形为高斯波、平面波 FDTD_二维/FDTD.zip , 6075 FDTD_二维/FDTD_31.m , 1029 FDTD_二维/FDTD_32.m , 2806 FDTD_二维/FDTD_33.m , 3782 FDTD_二维/FDTD_34.m , 4182 FDTD_二维/FDTD_35.m , 4793...