并发笔记(二)

并发容器

  • ConcurrentHashMap:线程安全的HashMap,在高并发场景下比Collections.synchronizedMap性能好
  • CopyOnWriteArrayList:读多写少的场合性能远好于Vector,写的时候加的重入锁,并且每次增加元素都会重新拷贝一个新数组替换老数组;读的时候不加锁;
  • ConcurrentLinkedQueue:高效的并发队列使用链表实现
  • BlockingQueue:阻塞队列接口,可作为数据共享通道
  • ConcurrentSkipListMap:有序、安全、层级随机、空间换性能

锁优化

  • 优化原则

    • 减小锁持有时间,
    • 减小锁粒度,尽量减小加锁的代码块
    • 读写分离锁替换独占锁
    • 锁分离,如(LinkedBlockingQueue put方法和take方法不同的锁)
    • 锁粗化,频繁获取锁的时候,可考虑进行锁粗化
  • Java虚拟机对锁的优化

    • 锁偏向:如果一个线程获得了锁,那么锁进入偏向模式,如果该线程再次请求锁时,无需做任何同步操作,适合竞争不太激烈的场合,-XX:+UseBiasedLocking
    • 轻量级锁:将对象头部作为指针,指向持有锁的线程堆栈内部来判断一个线程是否持有锁,如果线程获得轻量级锁则进入临界区;否则锁膨胀
    • 自旋锁:锁膨胀后,为避免当前线程立即被挂起又获取锁之间的性能损耗,于是让当前线程做几个空循环(自旋),如果还能得到锁就进入临界区,否则挂起
    • 锁消除:在进行编译时通过逃逸分析技术可实现锁消除(不需加锁的地方被认为错误加锁,虚拟机可以将此类的锁进行消除)
  • ThreadLocal

    • 线程的局部变量,线程安全
    • 使用ThreadLocalMap挂到Thread上存储数据,其初始容量为16,后续容量均以2的指数增长(其hash算法能保证容器大小为2的指数时均匀分布);
  • 无锁

    • CAS (Compare And Swap):cas(v, e, n) 原子操作,v标识要更新的变量,e表示预期值,n表示新值,仅当v=e时,才会将v设置为n,多个线程竞争时只有一个会成功;
    • 基于CAS的原子操作类:AtomicInteger AtomicLong ...
    • unsafe: 封装了类似指针的操作,提供了类似CAS的原子性操作
    • AtomicStampedRefrence 可记录对象修改状态信息
    • 无锁的数组:AtomicIntegerArray AtomicLongArrary
    • 普通变量进行原子操作的支持:AtomicIntegerFieldUpdater AtomicReferenceFieldUpdater,[1、变量必须可见 2、必须是volatile 3、不能使static变量]
    • SynchronousQueue

并行模式与算法

  • 不变模式:对象一旦创建,其内部状态不再改变,如String 以及基本类型包装类;不变模式通过规避问题的态度来处理多线程的访问控制
  • 生产者与消费者:
    • 普通实现:通过BlockingQueue来进行数据缓存以达到生产者和消费者解耦
    • 无锁实现:利用Disruptor框架来实现,核心在于其使用环形队列(RingBuffer)来代替普通线性队列;生产者写入数据时、消费者消费数据时使用CAS操作确保数据安全。
  • Future模式:
    Future
  • 并行搜索:如果有序则使用二分查找,否则将整体数组切分成若干段,然后单独线程基于小段进行搜索
  • 并行排序:大多排序算法都是串行的,如果改为并行排序会增加算法复杂度
    • 奇偶交换排序:将奇偶交换进行并行
    • 并行希尔排序:根据希尔数值将分割成的小数组进行排序,然后重新计算希尔数值分割小数组,直到1为止;h>n的时候使用多线程;
  • NIO : 同步非阻塞
    • Channel 数据从channel读到buffer中,也可以将数据从buffer写到channel中
    • Buffer 用于与NIO通道的交互,一般分位4个步骤:
      • 写入数据到buffer
      • 调用flip()方法,从写模式切换到读模式
      • 从buffer中读取数据
      • 调用clear()或者compact()方法,清空缓存区等待再次写入
    • Selector 检测一到多个NIO通道,并能检测到通道是否为读写做好准备的组件;使用时,Channel应向Selector中进行注册(只接受非阻塞Channel)
  • AIO :异步非阻塞
    • 不会加快IO,只在读完后进行通知
    • 使用回调函数进行业务处理

参考资料《实战Java高并发程序设计》

猜你喜欢

转载自blog.csdn.net/u010209217/article/details/79081081