理解Java并发编程

article/2025/9/16 23:52:04

计算机基础

  1. 要想理解Java多线程,一定离不开计算机组成原理和操作系统,因为,java的多线程是JVM虚拟机调用操作系统的线程来实现的
/*Thread.start() 方法中调用了原生的start0()方法
*/
public synchronized void start() {if (threadStatus != 0)throw new IllegalThreadStateException();group.add(this);boolean started = false;try {start0();started = true;} finally {try {if (!started) {group.threadStartFailed(this);}} catch (Throwable ignore) {}}}// 原生方法private native void start0();
  1. 首先,先来理解CPU(处理器)的结构

在这里插入图片描述

解析每一个部件的功能,具体的细节不展开

  • ALU(算数逻辑单元):顾名思义是用来计算的,首先要知道一点,所有的信息在计算机看来都是0和1,通过加法运算,补运算, 异或运算等各种运算,完成数据的计算
  • CU (控制单元) : 可以理解为控制ALU运算(比如运算什么,怎么运算,以及运算的次数)
  • Register (寄存器): 用来存储ALU计算的中间数值
  • pc(程序计数器):用来记录某个线程运行到那个指令了
  1. 程序的加载过程以及是如何运行的

在这里插入图片描述

理解:程序,进程,线程

举例:比如我现在点击了WX.exe的程序,计算机会将WX程序加载到内存,这是在内存中的就是一个WX进程,每一个进程都有一个main线程,ALU找到main线程开始执行

程序:就是一段待执行的代码

进程:将程序这段代码以及所需要的数据加载到内存

线程:CPU,调度的基本单位

  1. 再来理解一个常识性的问题:我们买的电脑几核几线程的概念

    我们可以通过cmd的命令查看一下自己的电脑(华为matebookpro)

    以我自己的电脑为例 四核八线程

wmic

在这里插入图片描述

获取cpu的名称 cpu get name

在这里插入图片描述

获取cpu的核心数 cpu get numberofcores

在这里插入图片描述

也可以通过更加直观的方式, 打开任务管理器
在这里插入图片描述

可以很直观的看出有一个插槽,四个内核,八个逻辑处理器

解释

在这里插入图片描述

一个插槽说明只有一个物理cpu

四个内核说明有四个ALU

八个逻辑处理器说明每个ALU可以在Register中切换,可以减少线程的挂起

以前的cpu没有使用多核和超线程技术,也就意味着一个物理cpu对应一个内核对应一个线程,效率是极其低下的

线程的安全性

  1. 什么是线程安全?

    • 当多个线程访问某个类时,不管运行的环境(linux/windows)采用何种的调度方式或者这些线程将如何交替的运行,在主程序中不采用任何额外的同步或协同,这个类都可以表现出正确的行为。
    • 无状态的对象一定是线程安全的(也就是说该对象中的属性被多个线程共享)
  2. 原子性

    要想理解原子性首先要理解几个概念

    竞态条件:

    1. 专业术语:由于不恰当的执行顺序而出现不正确的结果的这种情况

    2. 个人理解:线程由于cpu的调度,多个线程交替执行,要得到正确的结果需要运气成分

      // 比如在单例模式中
      if (instance == null) {instance = new Singletion();
      }//这个过程是  先检查再执行,这个过程是可以被cpu打断的先检查再执行就是一个竞态条件
      
      //比如  count++//count++ 不是一步执行完成的需要先从内存中读取,在做修改,在写回内存读取 - 修改 - 写入  也是一个竞态条件
      

    复合条件:

    1. 专业术语:一组需要以原子的方式执行(不可分割)的操作
    2. 个人理解:就是不可以被cpu的调度所打断,必须执行完毕

    数据竞争:

    1. 这个很好理解,就是多个线程可以同时去写入或读出一个变量
  3. 加锁机制

    加锁机制可以保证原子性,也就是把一系列的操作变为原子的

    • 内置锁

      内置锁其实很简单,就是改变了,对象里的markword

      			// 使用这个依赖可以查看对象的结构				<dependency><groupId>org.openjdk.jol</groupId><artifactId>jol-core</artifactId><version>0.10</version></dependency>
      
      public class JustTest {private static class T {int i;}// 不加synchronizedpublic static void main(String[] args) {T t = new T();// 打印对象的结构System.out.println(ClassLayout.parseInstance(t).toPrintable());}
      }
      

      在这里插入图片描述

      public class JustTest {private static class T {int i;}public static void main(String[] args) {T t = new T();synchronized (t) {System.out.println(ClassLayout.parseInstance(t).toPrintable());}}
      }
      

      在这里插入图片描述

    • 重入锁

      当一个线程请求一个未被持有锁的对象,JVM会记下所得持有者,并将计数器加一,若果同一线程再次获取锁,则计数器再加一,直到计数器的个数为0时被释放

      如果不可重入,下面的代码可能就会死锁

      // 父类持有锁,不能释放,而子类需要锁,二者僵持
      public class Widget {public synchronized void doSomething() {}
      }class LoggingWidget extends Widget {@Overridepublic synchronized void doSomething() {System.out.println(toString());super.doSomething();}
      }
      

      注:不是所有的数据都需要锁来保护,只有被多个线程同时访问的可变数据才需要通过锁来保护。

  4. 活跃性和性能

    活跃性:安全性的含义:永远不要发生糟糕的事情,而活跃性则关注于:某个事情最终会发生,但由于如此,就可能出现没有得到锁而死等的现象,或者无意中造成的无限循环

    性能:性能方面有很多问题例如,服务时间过长,响应不及时等,要在性能和安全编码之间相互的权衡,不要一味为了性能而去修改简单的并发程序


http://chatgpt.dhexx.cn/article/wa0jdJAo.shtml

相关文章

【并发编程】JAVA并发编程面试题合集

1.在Java中守护线程和本地线程的区别&#xff1f; Java中的线程分为两种&#xff1a;守护线程&#xff08;Daemon&#xff09;和用户线程&#xff08;User&#xff09;任何线程都可以设置为守护线程和用户线程&#xff0c;通过方法Thread.setDaemon(boolean)&#xff1b;true表…

Java并发编程概述

在学习并发编程之前&#xff0c;我们需要稍微回顾以下线程相关知识&#xff1a; 线程基本概念 程序&#xff1a;静态的代码&#xff0c;存储在硬盘中 进程&#xff1a;运行中的程序&#xff0c;被加载在内存中&#xff0c;是操作系统分配内存的基本单位 线程&#xff1a;是cpu执…

java并发编程(并发编程的三个问题)

什么是并发编程? 首先我们要知道什么是并发? 什么是并行? 并行: 多件事情在同一时刻同时发生 并发: 在同一时间内,多个事情交替执行 并发编程: 比如抢票,秒杀等在同一场景下,有大量的请求访问同一资源, 会出现一些安全性的问题,所以要通过编程来控制多个线程依次访问资源,称…

java并发编程(荣耀典藏版)

大家好 我是月夜枫&#xff0c;聊一聊java中的并发编程&#xff0c;面试工作中也许都会用到&#xff0c;参考了很大博主的博客&#xff0c;整理了很久的文章&#xff0c;虽然还没有全部整理完&#xff0c;后续慢慢更新吧。 并发编程 一、线程的基础概念 一、基础概念 1.1 进…

Java并发编程基础(一篇入门)

1 并发编程简介 1.1 什么是并发编程 所谓并发编程是指在一台处理器上 “同时” 处理多个任务。并发是在同一实体上的多个事件。多个事件在同一时间间隔发生。 并发编程&#xff0c;从程序设计的角度来说&#xff0c;是希望通过某些机制让计算机可以在一个时间段内&#xff0…

关于Java并发编程的总结和思考

编写优质的并发代码是一件难度极高的事情。Java语言从第一版本开始内置了对多线程的支持&#xff0c;这一点在当年是非常了不起的&#xff0c;但是当我们对并发编程有了更深刻的认识和更多的实践后&#xff0c;实现并发编程就有了更多的方案和更好的选择。本文是对并发编程的一…

Java 并发编程

目录 回顾线程 并发编程 并发编程 Java 内存模型(JMM) 编程核心问题--可见性,原子性,有序性 可见性 有序性 原子性 valatile 关键字 CAS&#xff08;Compare-And-Swap&#xff0c;比较并交换&#xff09; 原子类 java中的锁 乐观锁/悲观锁 可重用锁&#xff08;…

JAVA并发编程

并发编程 1.进程与线程 进程 程序由指令和数据组成&#xff0c;但这些指令要运行&#xff0c;数据要读写&#xff0c;就必须将指令加载至 CPU&#xff0c;数据加载至内存。在 指令运行过程中还需要用到磁盘、网络等设备。进程就是用来加载指令、管理内存、管理 IO 的。当一个…

阿里面试失败后,一气之下我图解了Java中18把锁

号外号外&#xff01;《死磕 Java 并发编程》系列连载中&#xff0c;大家可以关注一波&#xff1a; 「死磕 Java 并发编程04」说说Java Atomic 原子类的实现原理 「死磕 Java 并发编程03」阿里二面&#xff0c;面试官&#xff1a;说说 Java CAS 原理&#xff1f; 「死磕 Jav…

Java 是否应该使用通配符导入( wildcard imports)

这个问题应该是所有使用过 Java 第一课的人都会告诉你不要使用通配符导入。 主要问题 主要的问题是它使你的本地命名空间变得混乱。 用最简单的说法就是 Date 这个对象&#xff0c;你可能在 java.sql.Date 和 java.util.Date 都会有这个对象。 如果你使用通配符导入的话&…

Makefile中wildcard函数的应用理解

文章目录 前言 1 "*"通配符使用场景 2 "*"通配符实例 总结 前言 如果我们想定义一系列比较类似的文件&#xff0c;我们很自然地就想起使用通配符。make 支持三种通配符&#xff1a;"*"&#xff0c;"?" 和 "[...]"。这…

DNS Wildcard(DNS泛域名)

在DNS中&#xff0c;泛域名&#xff08;wildcard Resource Record&#xff09;可以被认为是一种合成RR的机制&#xff0c;借助于它&#xff0c;DNS服务器可以响应本来不存在的域名的请求&#xff0c;它的设计初衷是用来把所有邮件都转发到一个邮件系统&#xff08;当然&#xf…

Es 模糊查询 match,wildcard

Es 模糊查询的方式 要求&#xff1a; Es查询&#xff1a; 查询工单信息&#xff0c; 输入 “测试”&#xff0c;查出 form_name 为字段中有查询出含有符合内容的数据 match&#xff1a;分词模糊查询&#xff1a; 比如“Everything will be OK, All is well”&#xff0c;会被…

wildcard

[ruskyrhel7 test]$ lstest1 test123 test2 test317 test33 test335 test336 test44 testtest[ruskyrhel7 test]$ ls test?3test33[ruskyrhel7 test]$ ls test??3test123[ruskyrhel7 test]$ ls test*test1 test123 test2 test317 test33 test335 test336 tes…

Makefile中wildcard使用方法

Makefile中wildcard函数使用方法 在Makefile规则中&#xff0c;通配符会被自动展开。但在变量的定义和函数引用时&#xff0c;通配符将失效。这种情况下如果需要通配符有效&#xff0c;就需要使用函数“wildcard”&#xff0c;它的用法是&#xff1a;$(wildcard PATTERN…) 。…

通配符(WildCard)的使用

一、关于WildCard&#xff1a;一个web应用&#xff0c;有成千上万个action声明&#xff0c;可以利用struts2提供的映射机制把多个彼此相似的映射关系简化成一个映射关系&#xff0c;即通配符。 1.新建类 ActionWildCard&#xff0c;验证通配符的方法 2.1添加Student需要实践的两…

Elasticsearch 警惕使用 wildcard 检索!然后呢?

1、wildcard 检索定义 wildcard 检索可以定义为&#xff1a;支持通配符的模糊检索。 类似 Mysql 中的 like 模糊匹配&#xff0c;如下所示&#xff1a; Elasticsearch 中的 wildcard 使用方式如下&#xff1a; 通配符运算符是匹配一个或多个字符的占位符。 通配符支持两种&…

VIO你用对了吗

VIO&#xff08;Virtual Input/Output&#xff09;有两个主要功能 监测设计中的内部信号&#xff1b; 驱动设计中的内部信号。 既然是Virtual&#xff08;虚拟的&#xff09;&#xff0c;就表明这个输入或输出并不是真实存在于FPGA设计中。下图显示了VIO的输入、输出管脚。其…

VIO(notes) —— (3)VIO残差构建与IMU预积分

VIO残差构建与IMU预积分 一、VIO残差函数的构建1. 系统所需的状态变量2. 视觉重投影误差2.1 视觉重投影误差2.2 逆深度参数化2.3 VIO 中基于逆深度的重投影误差 3. 预积分模型由来及意义3.1 为什么需要预积分&#xff1f;3.2 怎么预积分&#xff1f;3.3 预积分是什么&#xff1…

深蓝学院VIO课程学习笔记 VIO概述

VIO概述 1. VIO整体概述 松耦合&#xff1a;各部分自己算自己的&#xff0c;最后单独把数据来算 紧耦合&#xff1a;同时考虑这两个问题&#xff08;效果更好&#xff09; IMUGPS精度可以达到cm级&#xff0c;但是受环境影响比较大 融合方案 采用卡尔曼滤波&#xff0c;当一边…