多线程问题

多线程性能问题

线程调度

锁竟争、IO读写等

  1. 上下文切换:上下文切换会挂起当前正在执行的线程并保存当前的状态,然后找到要执行的代码,唤醒下一个线程。(考虑简单计算情况)
  2. 缓存失效:切换其它线程,cpu原有的缓存可能就失效,需要重新缓存新的数据(通常线程调试器会设置最小执行时间,以减少上下文切换的次数)

线程协作

避免数据错乱(禁止编译器和CPU的重排序优化)同步数据(工作内存flush到主存,再refresh到其它线程工作内存)

线程池优点

创建线程开销

系统开销(任务比较简单的话,有可能使创建和销毁用资源比线程执行本身更大)、占用一定内存等资源,上下文切换,稳定性,垃圾回收压力

线程池好处

  1. 解决线程生命周期系统开销问题,加快响应速度
  2. 统筹内存和CPU的使用
  3. 统一管理资源

队列

阻塞队列 BlockingQueue

通常使用RenntrantLock以及它的Condition来实现

  1. ArrayBlockingQueue:容量满了,不会扩容 ReentrantLock+两个Condition,读写要先获得独占锁才能进行下一步。 读时队列为空,则线程进行读线程专属的notEmpty的Condition的队列中排队,等待写线程写入新的元素 写时队列为满,写线程进行写线程专属的notFull队列中排队,等待读线程将队列元素移除并腾出空间
  2. LinkedBlockingQueue:无界 内部有两把锁,分别锁住队列的头和尾
  3. SynchronousQueue:容量不是1,它不需要执行元素,直接传递
  4. DelayQueue:底层使用PriorityBlickingQueue实现
  5. PriorityBlockingQueue:支持优先级的无界阻塞队列
  6. LinkdedTransferQueue

阻塞方法:

  • take:获取并移除队列头结点,无数据则阻塞
  • put:队列未满,正常插入,队列已满,则阻塞

抛出异常方法:

  • add
  • remove
  • element:返回队首,不删除

返回结果,不抛出异常

  • offer:插入一个元素,成功返回true;可带超时时间
  • poll:移除并返回头节点,失败返回null,失败返回null;可带超时时间
  • Peek:返回头结点,不移除

非阻塞队列 ConcurrentLinkedQueue

内部使用CAS非阻塞算法+重试实现———->不需要阻塞,并且并发不是特别剧烈的场景

原子类

Atomic+基本类型

AtomicInteger

AtomicLong

AtomicBoolean

AtomicArray+基础类型

AtomicIntegerArray

AtomicLongArray

AtomicReferenceArray

Atomic+?+Reference

AtomicReference

AtomicStampedReference:添加了时间戳,解决了ABA问题

AtomicMarkableReference:多了一个绑定的Boolen值,可用于表示此对象已删除的场景

Atoimc+?+FieldUpdater

AtomicIntegerFieldUpdater

AtomicLongFieldUpdater

AtomicReferenceFieldUpdater

This entry was posted in Thread. Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.