java特种兵读书笔记(5-5)——并发之常见并发编程工具

CountDownLatch


线程join可以实现等待某些线程结束,但是它仅仅能等待结束,这种方式需要逐个去等待。而CountDownLatch是等待一个信号量,当信号量达到设定数字时,等待线程就会被激活了。

CyclicBarrier


可以重复使用。假设一个需要5个步骤的操作,每个步骤都需要3个线程工作,对每个步骤这三个线程都要同时开始,不管上一个步骤谁先结束。这种场景下,使用CyclicBarrier来统一每一个步骤的开始时间。

CyclicBarrier的内在是一个计数器,类似一种轮训的计数器,当然最简单的方式是利用叠加的数据与管理对象的总数进行求模,查看结果是否等于0。

Executors


一个提供静态方法的空壳,大多数情况下用来创建线程池、调度。例如Executors.newFixedThreadPool(10)用于创建一个长度为10的线程池——并不意味着创建线程池和调度池就必须使用它,没有它也照样可以实现。

比如new ThreadPoolExecutor(...)或者new ScheduledThreadPoolExecutor(...)传入指定参数也可以达到效果,因为Executors的一系列静态方法也是通过间接调用这样的构造方法来实现的。

这么做的好处有什么?new ThreadPoolExecutor(...)或者new ScheduledThreadPoolExecutor(...)在构造的时候需要传入很多复杂的参数,不同的参数会导致不同的运行结果。由参数细节不同导致结果不一样的方式很容易让人忘记具体参数的含义,所以java将常见的几种模型抽象出来,每种模型都有一个非常简单的入口参数,同时用自己的特定名称标识,这样写代码就不需要关注太多的细节了。

①Executors.newFixedThreadPool(int)

创建一个线程数固定的线程池,如果传入10,那么线程并行度最大为10,初始化为0,第一个任务创建时启动一个线程处理,如果更多任务导致一个线程处理不过来,就创建新的线程,最多10个线程,线程数在shutdown以前只增不减,如果10个线程依然处理不过来,更多的任务会放在阻塞队列中,默认阻塞队列是一个无界队列(new LinkedBlockingQueue<Runnable>())无参的构造函数)。

②Executors.newFixedThreadPool(int,ThreadFactory)

同上,只是ThreadFactory是自己定义的,它本身是一个接口,需要实现new Thread(Runnable r)方法,负责返回创建后的线程。这样可以自己设置相应线程参数,比如线程名称前缀等。默认会用DefaultThreadFactory来处理。

③Executors.newCachedThreadPool()

默认对线程并行数量没有上限,如果出现瞬间并发,那么所有并发的请求都会分配一个线程来处理,线程数会瞬间增加!如果有空闲线程,会执行新提交的任务,如果没有任何任务提交,线程会默认保持60秒时间,60s内没有获取任务的线程一般会回收。底层实现如下,60L是keepAliveTime:

return new ThreadPoolExecutor(0, Integer.MAX_VALUE,60L, TimeUnit.SECONDS, new SynchronousQueue<Runnable>());

④Executors.newCachedThreadPool(ThreadFactory)

同上,可以自定义ThreadFactory。

⑤Executors.newSingleThreadExecutor()

创建一个长度为1的线程池,它的目的是线程复用,提交的都是任务。还可以通过它来模拟一些资源不够用的情况。

⑥Executors.newScheduledThreadPool(int)

创建调度池,调度池是基于线程池来完成的,在这个基础上做进一步的包装,只是提供的功能要求定时调度。与之类似的方法还有所有带Scheduled字样的方法。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值