欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

并发知识点整理

程序员文章站 2022-06-28 16:36:51
并发知识点整理并发一 原子性、可见性、有序性二 进程三态三 JVM线程中的状态四 CAS操作解析(一种锁粒度极低的乐观锁)五 synchronized带来的重度锁,和线程一开始的偏向锁,和轻量级锁5.1 Java对象5.2 锁如何升级六 ThreadPoolExecutor线程池的概念和参数解析6.1 主要参数6.2 拒绝策略七 java中的并发集合并发一 原子性、可见性、有序性1)原子性: 内存模型的原子性变量操作2)可见性:因为在执行过程中,每个一个线程都有自己单独的内存空间,只有通过(vola...

并发

一 原子性、可见性、有序性

1)原子性: 内存模型的原子性变量操作
2)可见性:因为在执行过程中,每个一个线程都有自己单独的内存空间,只有通过(volatile,synchronized,final)新值才能够立即进入到主存之中
3)有序性:线程内有序,线程间无序。通过,先行发生原则和,volatile,synchronized

二 进程三态

并发知识点整理
1)
运行态 —> 阻塞态:正在执行的进程因为某种等待事件无法执行,就进入了阻塞态
运行态 —> 就绪态:分配给每个进程的时间片是有限的,运行时间片使用完成之后或者出现更高优先权进程就进入到就绪态
就绪态 —> 运行态: 由CPU进行调度,选中一个进程分配时间片执行
阻塞态 —> 运行态: 进程所等待的事件已经发生

三 JVM线程中的状态

并发知识点整理

  1. 线程创建
  2. 线程在可运行状态
  3. 在线程未争取到锁对象的时候,线程进入锁阻塞,等待获取锁对象,进入可运行状态
  4. 线程获取到锁对象,但是调用了wait()方法,进入了无线等待中,等待其他线程调用notify(),只有获取锁对象才进入到可运行状态
  5. sleep时间到,或者wait时间到,进入到计时等待,时间到获取到锁对象才能进入可运行状态,时间到未获取到锁对象就进入锁阻塞状态
  6. 线程终止

四 CAS操作解析(一种锁粒度极低的乐观锁)

AtomicInteger.incrementAndGet();

public final int incrementAndGet() {
    return unsafe.getAndAddInt(this, valueOffset, 1) + 1;
}
public final int getAndAddInt(Object var1, long var2, int var4) {
    int var5;
    do {
    var5 = this.getIntVolatile(var1, var2);
} while(!this.compareAndSwapInt(var1, var2, var5, var5 + var4));
    return var5;
}

1.它包含 3 个参数 CAS(V,E,N),V表示要更新变量的值,E表示预期值,N表示新值。仅当 V值等于E值时,才会将V的值设为N,如果V值和E值不同,则说明已经有其他线程做两个更新,则当前线程则什么都不做。最后,CAS 返回当前V的真实值。

2.compareAndSwapInt 是一个native接口

3.底层实现原理: 通过 mov 指令 ,移动exchange_value 等值 ,进入寄存器中,然后通过累加器,进行值的计算,最后通过总线,刷新主存,达到效果

五 synchronized带来的重度锁,和线程一开始的偏向锁,和轻量级锁

并发知识点整理

5.1 Java对象

  1. 对象头+实例数据+对齐填
  2. Mark Word+指向对象所属的类的指针组成(如果是数组对象,还会包含长度
    并发知识点整理

5.2 锁如何升级

  1. 偏向锁 —> 轻量级锁 —>重量级锁
  2. 偏向锁升级:当一个线程获得了偏向锁,在执行时,只要有另一个线程尝试获得偏向锁,并且当前持有偏向锁的线程还在同步块中执行,则该偏向锁就会升级成轻量级锁。
  3. 轻量级锁升级:用CAS操作将锁的Mark Word替换为自己线程栈中拷贝的锁记录的指针。如果成功,当前线程获得锁,如果失败,表示Mark Word已经被替换成了其他线程的锁记录,说明在与其它线程竞争锁,当前线程就尝试使用自旋来获取锁。当自选次数超过一定次数,就升级为重量级锁

六 ThreadPoolExecutor线程池的概念和参数解析

6.1 主要参数

参数名 参数含义
corePoolSize 核心线程数
maxinumPoolSize 最大线程数
keepAliveTime 空闲线程存活时间
unit 存活时间的单位
workQueue 存放线程任务队列
threadFactory 线程工厂,创建新线程
handler 线程池拒绝处理后的任务

并发知识点整理
corePoolSize : 代表核心线程数,这些线程创建以后并不会被消除,而是一种常驻线程
maxinumPoolSize : 表示最大允许被创建的线程数,当核心线程数都用完时
workQueue : 用来存放待执行的任务,假设我们现在核心线程都已被使用,还有任务进来则全部放入队列,直到整个队列被放满但任务还再持续进入则会开始创建新的线程
keepAliveTime、unit : 表示超出核心线程数之外的线程的空闲存活时间,也就是核心线程不会消除,但是超出核心线程数的部分线程如果空闲一定的时间则会被消除
threadFactory : 线程工厂,用来生产线程执行任务
handler : 有两种触发任务拒绝策略的方法,1.调用shutdown 2.线程池内已经达到最大线程数,这个时候也是拒绝

6.2 拒绝策略

  1. ThreadPoolExecutor.AbortPolicy:丢弃任务并抛出RejectedExecutionException异常。
  2. ThreadPoolExecutor.DiscardPolicy:也是丢弃任务,但是不抛出异常。
  3. ThreadPoolExecutor.DiscardOldestPolicy:丢弃队列最前面的任务,然后重新尝试执行任务(重复此过程)
  4. ThreadPoolExecutor.CallerRunsPolicy:由调用线程处理该任务

6.3 线程池的两种提交方式 submit 和 execute

  • execute只能提交Runnable类型的任务,无返回值。submit既可以提交Runnable类型的任务,也可以提交Callable类型的任务,会有一个类型为Future的返回值,但当任务类型为Runnable时,返回值为null。
  • execute在执行任务时,如果遇到异常会直接抛出,而submit不会直接抛出,只有在使用Future的get方法获取返回值时,才会抛出异常。

6.4 workQueue

  1. SynchronousQueue:阻塞队列
  2. LinkedBlockingQueue:无限队列
  3. ArrayBlockingQueue:由数组支持的有界阻塞队列,FIFO

七 java中的并发集合

  1. CopyOnWriteArrayList相当于线程安全的ArrayList

  2. CopyOnWriteArraySet相当于线程安全的HashSet

  3. ConcurrentHashMap相当于线程安全的HashMap

  4. ConcurrentSkipListMap相当于线程安全的TreeMap

  5. ConcurrentSkipListSet相当于线程安全的TreeSet

  6. ArrayBlockingQueue是数组实现的线程安全的有界的阻塞队列

  7. LinkedBlockingQueue是单向链表实现的(可指定大小)阻塞队列

  8. ConcurrentLinkedQueue是单向链表实现的*队列

本文地址:https://blog.csdn.net/m0_37111373/article/details/113944012