多线程
[编程语言教程]

进程和线程的区别

  • 进程是资源分配的最小单位,线程是程序执行的最小单位。
  • 进程有自己独立的地址空间,线程使用相同的地址空间共享数据。
  • 线程的切换,开销,所占的资源少。

Synchronized

  • 对象:对象头(Mark Word,Class Point,Monitor),实例信息,对齐填充。
  • 同步方法:读取ACC_SYNCHRONIZED标志位实现。
  • 同步代码块:monitorenter,monitorexit。
  • 偏向锁:一个线程常常获得同一个锁。轻量级锁:线程少,持有锁的时间短,自旋等待锁释放。重量锁:没有持有锁的线程阻塞,防止空转。
  • 锁优化:锁的升级,偏向锁(不会主动释放)比较对象头和线程的threadID检查线程存活升级,轻量级锁自旋升级,重量级锁阻塞没有锁的线程,防止CPU空转;锁粗化,避免频繁加锁;锁消除,逃逸分析去除没必要的锁。
  • 类锁:修饰静态方法或类(class)。对象锁:修饰方法或代码块(this)。两者不冲突。

Lock

  • ReenTrantReadWriteLock: ReadLock的获取需要当前线程持有读(重入)/写(再次获取)锁,其他线程没有没有写锁;WriteLock的获取需要当前线程持有写锁,没有锁且CAS成功。写锁的个数为0才能认为锁释放成功。

  • ReentrantLock:非公平锁在调用lock后,会进行一次CAS抢锁,失败后和公平锁一样进入到tryAcquire方法,在该方法中,发现锁释放会再次CAS抢锁,公平锁会查看是否有线程在等待。

  • AQS(抽象队列同步器):提供了一种阻塞锁和依赖FIFO等待队列同步器的框架。核心机制基于CLH队列(不存在队列实例,仅存在节点关系)实现,将请求资源的线程封装成CLH队列的一个Node来实现锁的分配。实现共享资源state的获取和释放方式(acquire独享,acquireShared共享)定义独享(ReentrantLock)和共享(Semaphore)。

  • CAS:用CPU指令实现无锁的数据操作,提高效率。缺点:CAS长时间不成功会增加CPU开销;只能保证一个共享变量的原子操作,多个变量操作需要用到锁;ABA(AtomicStampedReference标志解决)。

  • StampedLock:乐观锁,相对于读写锁的改进在于,读的过程中允许线程获取写锁后写入。为了避免读取不一致的情况,需要判断读的过程中是否有写入。

ThreadLocal

  • 指定线程存储数据,维护自己的变量副本/拷贝。set,get方法。

  • 内存泄漏:ThreadLocalMap存在Key弱引用ThreadLocal的Entry,threadlocal被回收后,出现null Key无法找到value。解决方法:每次使用完ThreadLocalMap,调用threadlocal的remove方法。

技术图片

  • 解决的问题:适用变量在线程中隔离,在方法中共享的场景;减少了临界区的范围;减少了线程的切换。

  • Spring对Bean(singleton作用域)中非线程安全状态采用ThreadLocal进行处理,解决线程安全问题。

volatile

  • MESI(缓存一致性协议):其他CPU存在变量副本时缓存行置为无效状态;锁bus;总线风暴,嗅探机制与CAS不断失败交互(部分使用Synchronized)。
  • 变量是volatile的,每次读变量都从内存中读取。
  • 可见性:线程修改变量值能立即同步到主内存,每次使用前从主内存中刷新。嗅探机制检查缓存是否过期,缓存行对应的内存地址修改则强制失效。
  • 有序性:禁止指令重排序;happens-before(volatile变量的写happens-before读);as-if-serial(单线程执行结果不变)。

线程池

  • 种类:newCachedThreadPool,newFixedThreadPool,newScheduledThreadPool,newSingleThreadExecutor。
  • 主要参数:核心线程数:线程进入工作队列,工作队列满时创建超过这个数量的线程;最大线程数空闲时间:线程数大于核心线程数时,未执行任务达到空闲时间则终止;缓冲队列:LinkedBlockingQueue;ArrayBlockingQueue;SynchronousQueue(生产者线程对其的插入操作put必须等待消费者的移除操作take)。工厂方法:指定不同线程池类型;拒绝策略:缓存队列已满,线程达到上限。抛出异常,丢弃或丢弃最早的,重试;Hash表维护线程的引用;submit:使用future获取任务的执行结果。
  • 执行过程:核心线程->队列->最大线程->拒绝策略。
  • 运行状态:有volatile修饰的状态码;corePoolSize,maxPoolSize,largestPoolSize。
  • JUC: tools:工具类;executor:执行线程的工具;atomic:原子性包;locks:锁包;collections:线程安全的集合。
  • 线程间的通信:wait/notify机制;volatile修饰的全局变量;消息队列;事件。
  • 线程间的同步:互斥量(共享资源不会被多个线程所访问,同步不同进程的线程),临界区(保证同一时刻只有一个线程访问数据,同步进程内的线程),信号量事件
  • ThreadLocal用于解决线程数据隔离问题。
  • 读写锁适用于读多写少的场景。
  • 生产者与消费者模式(生产和消费通过内存缓冲区通信):锁;信号量;线程通信;阻塞队列。
  • 线程状态:新建,就绪,运行,阻塞,死亡。
  • 获取线程状态:Thread.getState()
  • CountDownLatch:原子计数器,调用CountDownLatch对象的countDown方法计数器为0时才执行await方法。
  • 垃圾清除算法:标记清除(老年代),扫描两次,空间碎片;标记复制(新生代);引用计数;标记整理。

多线程

原文地址:https://www.cnblogs.com/ash1523590342/p/13461618.html

hmoban主题是根据ripro二开的主题,极致后台体验,无插件,集成会员系统
自学咖网 » 多线程