并发

什么是并发?

并发是指在同一时间段内,系统中有多个独立的任务同时执行的能力。

为什么要有并发?

提高系统的吞吐量、响应性和资源利用率。

并发能力怎么实现?

并行(计算机硬件必须支持)

多进程的并发(操作系统中同时运行的多个应用程序)

多线程的并发(同一个进程中同时运行的多个任务)(多个线程共享进程的内存空间和上下文环境,上下文切换的代价更小)

并发带来了哪些问题?

1.上下文切换代价过大:

​ 无锁并发编程、CAS算法、避免少任务多线程、协程(单线程多任务)

2.资源的限制程序的执行速度 上传/下载速度、连接数:

​ 增加资源(扩充资源、集群)、限制并发度

3.数据的不一致性 共享数据(程序内部的数据、外部数据)的不一致

4.死锁

​ 正确的使用锁

5.调试难度过大

程序内部的数据一致性

​ 主内存

【线程A 缓存】 【线程B 缓存】

1.比如 主内存中有变量 data1 = 0 , data2 = 0 ,data3 = 0 ,data4 = 0;

2.线程A 执行{ data1 = 1 ; data2 = data3} ;线程B执行 {data3 = 1;data4 = data1};

3.理想状态不发生重排序:data2:data4 可能的结果 0:1 1:0 1:1 实际还会出现在未重排序的情况下出现 0:0

可见性:volatile(易变的) synchronized Lock 确保修改后的数据会立即同步上主内存,其它线程会直接从主内存上读取

原子性: atomic(CAS[乐观锁的模式] + volatile) synchronized Lock

有序性:synchronized(同步:同一时刻只能有一个线程进入代码块) Lock(锁) volatile(禁止指令重排序)

as-if-serial规则(对重排序的一个保证): 编译器和处理器不会对存在数据依赖关系的操作做重排序

happens-before规则(对数据可见性的一个保证):如果一个操作happens-before另一个操作,那么第一个操作的执行结果将对第二个操作可见,而且第一个操作的执行顺序排在第二个操作之前(并不是强制性的,如果重排序后的执行结果与按happens-before规则执行的结果一致,则可能重排序)。

如何建立 happens-before关系:

程序次序:一个线程中的每个操作,happens-before于该线程中的任意后续操作。

监视器锁规则: 解锁 happens-before 加锁

volatite变量修饰: 对一个volatile域的写,happens-before于任意后续对这个volatile域的读

线程start和join: 当一个线程start或join线程时,第一个线程执行的任何操作都“happens-before”第二个线程执行的任何操作。

线程中断: 如果一个线程中断另一个线程,那么第一个线程执行的任何操作都“happens-before”被中断线程执行的任何后续操作。

对象终结规则:一个对象的初始化完成happen-before 于 finalizer() 方法的开始

happen-before的传递性: 如果操作A“happens-before”操作B,并且操作B“happens-before”操作C,则操作A“happens-before”操作C。

控制线程对共享资源的访问(线程之间的同步)

1.synchornized wait notify

2.ReentrantLock Condition

3.ReadWriteLock

4.StampedLock

5.Semaphore

6.CountDownLatch

7.CyclicBarrier

8.Phaser

9.Exchanger

10.FutureTask

11.CompletableFuture

CompletableFuture是Java 8引入的一个新特性,用于实现异步编程并发操作

  1. 异步执行:可以使用CompletableFuture.runAsync()或者CompletableFuture.supplyAsync()方法来创建一个异步任务,并通过thenApply()、thenAccept()等方法对任务进行串行和并行操作。
  2. 回调机制:可以使用CompletableFuture.thenApply()、thenAccept()等方法来设置回调函数,当异步任务执行完成后,会自动触发回调函数进行后续处理。
  3. 异常处理:可以使用CompletableFuture.exceptionally()或者handle()方法来处理异步任务执行过程中可能出现的异常情况,并对异常进行捕获和处理。
  4. 组合操作:可以使用CompletableFuture.thenCompose()或者allOf()等方法将多个异步任务进行组合操作,从而达到更高效的并发处理效果。
  5. 线程池支持:可以使用CompletableFuture.supplyAsync()方法传递线程池参数,从而控制异步任务的执行所在的线程池,保证线程安全和高效性。

12.ArrayBlockingQueue

1
2
3
ReentrantLock
阻塞队列
先进先出(FIFO)

java volatile=lock+编译器内存屏障

c/c++ + volatile=


并发
https://bolg.pengfanao.top/2024/08/01/后端/并发/
作者
pfa
发布于
2024年8月1日
许可协议