美文网首页
9.J.U.C之AQS

9.J.U.C之AQS

作者: JarvisTH | 来源:发表于2019-11-28 23:55 被阅读0次

一、介绍
AQS是J.U.C的核心,AQS是AbstractQueuedSynchronizer的简写。


1.使用Node实现FIFO队列,可以用于构建锁或者其他同步装置基础框架。

2.利用一个int类型表示状态。

3.使用方法是继承。

4.子类通过继承并实现它的方法管理其状态{acquire和release}的方法操纵状态。

5.可以同时实现排他锁和共享锁模式。

组件:CountDownLatch、Semaphore、CyclicBarrier、ReentrantLock、Condition、FutureTask。

二、CountDownLatch
主要是await方法,countDown方法,await方法等待countDown减为0后执行后面的代码。wait方法还可以指定时间。

三、Semaphore
主要是acquire和release方法,主要用于有限资源。可以丢弃没有请求到资源的请求,tryAcquire方法,还可以设置超时时间。

四、CyclicBarrier
允许多个线程相互等待,当每个线程准备就绪时才能继续向下执行。如果await指定了超时时间,可能抛出异常导致中断,要继续执行可以捕捉异常。

五、ReentrantLock
1.ReentrantLock与synchronized区别:

  • 可重复性:前者可重入。
  • 锁实现:前者JDK实现,后者JVM实现。
  • 性能区别:相差不大。推荐synchronized。
  • 功能区别:方便性synchronized高,细腻度ReentrantLock高。

2.ReentrantLock独有功能:

  • 可指定公平锁还是非公平锁
  • 通过Condition类,可以分组唤醒需要唤醒的线程
  • 通过能够中断等待锁的线程的机制,lock.lockInterruptibly()。

ReentrentReadWriteLock:在没有读锁和写锁时,可以加写锁;写入很少读取很多时,容易导致写线程饥饿。

StampedLock等。

六、FutureTask
Future可以监视目标线程调用call的情况,可以得到线程任务方法的返回值。FutureTask结合了Future和Callable等接口,功能强大,适合使用线程完成任务,关心任务结果及正常执行情况。

七、Fork/Join框架
主要采用工作窃取算法。

八、BlockingQueue
线程安全,适用于生产者-消费者场景。


1.ArrayBlockingQueue:容量有限,初始化指定容量。
2.DelayQueue:一般按元素过期的优先级排序,适用于定时任务等。
3.LinkedBlockingQueue:初始化不指定大小则是无边界的。
4.PriorityBlockingQueue:无边界队列,允许插入空对象,有排序的队列。
5.SynchronousQueue:只允许插入一个元素,插入后被阻塞,除非被另一个队列取走。

九、线程池
1.new Thread弊端:

  • 每次new Thread新建对象。性能差。
  • 线程缺乏管理,可能无限制的新建线程,相互竞争,可能占用过多系统资源导致死机或者OOM。
  • 缺少更多功能,如更多执行、定期执行、线程中断。

2.线程池好处:

  • 重用存在的线程,减少对象创建、消亡的开销,性能好。
  • 可以有效控制最大并发线程数,提高系统资源利用率,同时可以避免过多资源竞争,避免阻塞。
  • 提供定时执行、定期执行、单线程、并发数控制等功能。

3.ThreadPoolExecutor:

  • corePoolSize:核心线程数量,
  • maximunPoolSize:线程最大线程数
  • workQueue:阻塞队列,存储等待执行的任务,对线程池允许影响重大。

运行的线程数少于corePoolSize,直接创建新线程处理任务,即使其他线程是控线的。线程数大于等于corePoolSize,且小于maximumPoolSize时,则只有当BlockingQueue队列满时,才创建新任务。若corePoolSize和maximumPoolSize大小相等,则创建的线程池大小固定,有线程提交且BlockingQueue还没有满时,则加入BlockingQueue等待有空闲线程取出任务。若运行的线程数量大于指定的最大线程数时,若BlockingQueue也满了,则通过拒绝策略参数指定策略去处理这个任务。

若想降低系统消耗,可以设置一个较大的队列容量和一个较小的线程池容量,降低线程处理任务的吞吐量。

  • KeepAliveTime:线程没有任务执行时最多保持多久时间终止。
  • unit:keepAliveTime的时间单位。
  • threadFactory:线程工厂,创建线程。
  • rejectHandler:拒绝策略,有四种策略:直接抛出异常、调用线程执行任务、抛弃阻塞队列中最靠前的任务并执行当前任务、直接丢弃当前任务。
  • execute():提交任务给线程池执行
  • submit():提交任务,能够返回执行结果execute+Future
  • shutdown():关闭线程池,等待任务都执行完
  • shutdownNow():关闭线程池,不等待任务执行完。
  • getTaskCount():线程池已执行和未执行的任务总数
  • getCompletedTaskCount():已完成的任务数量
  • getPoolSize():线程池当前线程数量
  • getActiveCount():当前线程池中正在执行任务的线程数量


    线程池类图
  • Executors.newCachedThreadPool:可缓存的线程池,如果线程池长度超过处理的需要,可以灵活回收空闲线程;如果没有可以回收的,就新建线程。
  • Executors.newFixedThreadPool:创建一个定长线程池,可以控制线程的最大并发数,超出的线程会在队列中等待。
  • Executors.newScheduledThreadPool:创建定长线程池,支持定时任务和周期任务。
  • Executors.newSingleThreadExecutor:创建单线程线程池,保证任务按指定顺序执行。

合理配置

  • CPU密集型任务,需要尽量压榨CPU,参考值可以设为NCPU+1
  • IO密集型任务,参考值可以设置为2*NCPU

相关文章

  • 9.J.U.C之AQS

    一、介绍AQS是J.U.C的核心,AQS是AbstractQueuedSynchronizer的简写。 2.利用一...

  • 知识梳理目录

    Java基础 Java线程池 AQS之独占锁 AQS之Condition AQS之Condition AQS之同步...

  • J.U.C之AQS:大话AQS详解和使用

    J.U.C之AQS:AQS详解和使用 AQS是什么 AQS是AbstractQueuedSynchronizer的...

  • AQS之同步器

    AQS之独占锁AQS之共享锁AQS之Condition 在了解了AQS的实现原理之后再来看这些同步器会觉得很亲切,...

  • J.U.C 之AQS

    J.U.C 之AQS AbstractQueuedSynchronizer - AQS 实现原理 使用Node实现...

  • 「死磕Java并发」—–J.U.C之AQS(一篇就够了)

    J.U.C之AQS传送门 【死磕Java并发】—–J.U.C之AQS(一篇就够了) ,作为同步组件的基础,AQS做...

  • 深入浅出AQS系列文章汇总

    汇总一下四篇AQS文章,跟写文章的顺序不同,这个顺序更适合阅读。 深入浅出AQS之组件概览深入浅出AQS之独占锁模...

  • 深入浅出AQS之组件概览

    之前分析了AQS中的独占锁,共享锁,条件队列三大模块,现在从结构上来看看AQS各个组件的情况。 深入浅出AQS之独...

  • java并发之AQS原理

    java并发之AQS原理 知识导读 AQS定义了同步队列+阻塞线程+唤醒线程的基本实现。是否该阻塞(tryAcqu...

  • Java 多线程

    J.U.C 之 AQS (AbstractQueuedSynchronizer) http://www.cnblo...

网友评论

      本文标题:9.J.U.C之AQS

      本文链接:https://www.haomeiwen.com/subject/vrdbwctx.html