【JAVA-多线程并发-原子-锁机制】

本文详细阐述了程序和进程的基本概念,重点讲解了进程与线程的区别,CPU工作原理及多线程编程中的原子操作,死锁问题及其解决方案,以及Java中的AQS抽象队列同步器在并发控制中的重要角色。
摘要由CSDN通过智能技术生成

我们探讨有关 多线程并发-原子-锁机制原理-死锁 的问题。

1.我们先了解一个概念,什么是程序?

程序分为两个状态,

非运行状态下: 代码文本 + 资源数据

运行状态下:进程
2.进程与线程的区别?
进程:通过调度计算机资源 (CPU+RAM+IO), 利用现有数据来解决问题的一套指令集 ( 代码 )。
线程:CPU执行时最小调度单元。
当一个进程被创建时,它至少会创建一个线程,称为 主线程
主线程可以创建其他线程,这些线程称为 子线程。子线程可以与主线程并行执行。
3.线程在CPU中运行,CPU的概念?

CPU(中央处理器):是计算机的核心部件,负责处理计算机中的数据和指令。CPU也被称为处理器或微处理器。

核心数量 + 线程数量

4核心8线程使用超线程技术,把一个物理核心,模拟成两个逻辑核心。每个物理核心可以同时执行2个线程,因此总共有8个线程可以同时执行。

CPU线程数量:一般是4-32 ,64以上一般用于服务器大计算的功能。

操作系统实际运行线程数量:2000-10000

 此处为8核16线程,正在运行线程数量3880左右。CPU使用16个逻辑处理器,处理3880个线程(每个逻辑处理器同时智能处理一个线程)

CPU的主要功能:

  • 执行指令:CPU从内存中读取指令,并根据指令对数据进行处理。
  • 进行运算:CPU可以进行各种算术运算和逻辑运算,如加、减、乘、除、与、或、非等。
  • 控制设备:CPU可以控制计算机中的各种设备,如内存、硬盘、显卡、声卡等。

CPU由以下几个部分组成:

  • 运算器:执行算术运算和逻辑运算。
  • 控制器:控制CPU的各个部件,并协调CPU与其他设备之间的通信。
  • 寄存器:是CPU内部的临时存储器,用于存储指令、数据和地址等信息。
  • 总线:CPU与其他设备之间的数据通路。

CPU的工作原理如下:

  • CPU从内存中读取指令。
  • CPU将指令解码,并确定指令的操作码和操作数。
  • CPU根据指令的操作码和操作数执行相应的操作。
  • CPU将结果存储在寄存器或内存中。

CPU通过调度器来调度线程。通过下面常见的调度算法来执行:

  • 时间片轮转调度算法:将CPU时间划分为一个个时间片,每个线程轮流执行一个时间片。当一个线程的时间片用完时,它会被挂起,下一个线程开始执行。
  • 优先级调度算法:优先级高的线程会被优先执行。
  • 多级反馈队列调度算法:将线程分为多个队列,每个队列都有不同的优先级。当一个线程在高优先级队列中执行完后,它会被移动到低优先级队列中。

在多线程的CPU上面写多线程程序才能够真正提高效率。

4.八大原子操作

原子性:CPU能够保证在一条指令执行期间不会被中断,聪儿保证指令的完整性和数据的正确性。

八大原子操作是指在多处理器系统中,保证原子性的一组基本操作。分别是:

  1. 读-改-写 (Read-Modify-Write):在一个操作中读取一个值,修改它,然后将其写回。
  2. 加载链接 (Load-Link):将一个值加载到一个寄存器中,并将其与另一个寄存器中的值链接起来。
  3. 存储条件 (Store-Conditional):将一个值存储到一个内存位置,但只有当该内存位置满足某个条件时才会执行此操作。
  4. 交换 (Swap):交换两个寄存器中的值。
  5. 比较并交换 (Compare-and-Swap):将一个寄存器中的值与一个内存位置中的值进行比较,如果相等,则用另一个寄存器中的值替换内存位置中的值。
  6. 获取并添加 (Fetch-and-Add):将一个内存位置中的值加载到一个寄存器中,并将其与另一个寄存器中的值相加,然后将结果存储回内存位置。
  7. 递增 (Increment):将一个内存位置中的值递增 1。
  8. 递减 (Decrement):将一个内存位置中的值递减 1

5.线程安全问题

多线程程序中,因内存访问冲突数据竞争而导致程序行为不正确或崩溃的情况。

通常发生在多个线程同时访问共享数据时。线程安全问题有:

  • 数据损坏:当多个线程同时修改同一个数据时,可能会导致数据损坏。
  • 死锁:当多个线程都在等待对方释放锁时,可能会导致死锁。
  • 饥饿:当一个线程长时间无法获得锁时,可能会导致饥饿。
  • 不可预测的行为:当多个线程同时访问共享数据时,可能会导致程序行为不可预测。

使用同步机制来保证共享数据的访问是原子的:

  • :锁是一种用来保护共享数据的同步机制。当一个线程获取锁后,其他线程就不能访问被锁保护的数据,直到该线程释放锁。
  • 信号量:信号量是一种用来控制共享资源访问的同步机制。当一个线程获取信号量后,它就可以使用该资源。当该线程释放信号量后,其他线程就可以使用该资源。
  • 原子操作:原子操作是指在一条指令执行期间不会被中断的操作。原子操作可以使用专门的原子性指令来实现,例如加载链接/存储条件指令(LL/SC)和比较并交换指令(CAS)。
6.实现线程的方式
1)extends Thread
重写 run 方法 调用 start 方法启动
2)implements Runnable 接口 推荐
重写 run 方法 调用 start 方法启动
3)implements Callable 接口
重写call 方法 ( 返回值 ) 提交给线程池启动
7.Thread类 与 Runnable 接口的区别
  1. Thread 类继承自Object类,也实现了Runnable 接口。
  2.  Thread类中包含很多线程的管理方法。Thread实际上是一个工具类(管理线程的生命周期和线程信息),Runnable接口只能定义线程要执行的任务。
  3. Thread类是一个类,而Runnable接口是一个接口。
  4. Thread类提供了很多方法来控制线程的执行,比如start(),stop(),sleep()等,而Runnable接口只包含一个抽象方法run()
  5. Runnable接口的实现类可以被多个线程同时执行,而Thread类只能被一个线程执行。

Thread类的方法

  • start():启动线程。
  • run():线程执行体。
  • stop():停止线程。(不推荐使用)
  • sleep(long millis):使线程睡眠指定毫秒数。
  • join():等待线程终止。
  • join(long millis):等待线程终止指定毫秒数。
  • isAlive():检查线程是否还活着。
  • isDaemon():检查线程是否为守护线程。
  • setDaemon(boolean):设置线程是否为守护线程。
  • getName():获取线程的名称。
  • setName(String):设置线程的名称。
  • getPriority():获取线程的优先级。
  • setPriority(int):设置线程的优先级。
  • getId():获取线程的ID。

献上找的网图

8.synchronized:监视器锁,监视一个对象来作为锁的依据
  • 这个对象需要是多个线程同时可以看到一个对象;
  • 这把锁也是Java内置的隐式锁;
  • 代码执行完了就解锁,没执行完成就一直持有锁。

9.死锁问题
1.某一个线程一直持有锁,不解锁。
2. 两个线程之间互相持有对方需要的锁 :两个线程都持有了一把锁,接着都需要再持有一把锁(也是对方目前持有的锁 ) 才可以执行任务。        
        
解决:
1 : 不写死锁( 拿到一把锁 不获取另一把锁 )
2 : 获取一把锁之后 尝试获取第二把锁,失败的话,立马放弃第一把锁,再重新自旋
获取第一把锁
死锁发生的四个条件
  1. 互斥条件:一个资源只能由一个线程占用。
  2. 占有并等待条件:一个线程占有一个资源,同时等待另一个资源。
  3. 不可剥夺条件:一个资源只能由占有它的线程释放。
  4. 循环等待条件:存在一个等待资源的线程环路,即每个线程都在等待另一个线程释放资源。

如何预防死锁

  • 破坏互斥条件:允许多个线程同时访问同一个资源。
  • 破坏占有并等待条件:当一个线程请求一个资源时,如果该资源已经被另一个线程占用,则让请求资源的线程等待,直到该资源被释放。
  • 破坏不可剥夺条件:如果一个线程占有一个资源,但长时间没有使用该资源,则可以将该资源从该线程中剥夺,并分配给其他线程。
  • 破坏循环等待条件:确保不存在等待资源的线程环路。
10.AQS 抽象队列同步器

可以访问大佬的文章,AQS 通过一个双向的先进先出(FIFO)队列(同步队列)来管理等待线程,如果某个线程发现前驱的线程释放了锁,便会获得锁。

AQS(AbstractQueuedSynchronizer)详解 - 知乎 (zhihu.com)

我们可以创建一百个线程,对num进行 ++ 操作 ,每个线程中都是一个死循环,判断跳出循环的条件是num==100w。跳出后每个线程打印本线程执行了多少次。结果是每个线程可能都不一样,有的执行得多,有的执行得少。

如果用AQS,可以保证每个线程都执行1w次,使得线程之间的竞争消耗基本上没有,保证并发性能资源浪费程度非常低。JAVA并发做得好,很大程度上在于这一个类。 

  • 17
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值