【Concurrency】之 java.util.concurrent包(线程池,写入时复制,阻塞队列)

线程池


场景:
  1. 创建线程的代价虽然很低,但也没低到能直接忽视的程度,而每个连接都花费了这个代价
  2. 如果每个链接都创建一个线程,当请求连接的速度高于处理连接的速度时,系统的线程数也会随之快速增长,服务器将停止服务甚至奔溃。


来个线程池:
// 创建一个线程池,线程池的大小设为可用处理器数的2倍。
// 如果同一时间有超过线程池大小的execute()请求存在,超出的部分将进行排队直到某线程被释放。

int threadPoolSize = Runtime.getRuntime().availableProcessors() * 2;
ExecutorService executor = Executors.newFixedThreadPool(threadPoolSize);


线程池大小

影响因素有:硬件性能,线程任务是CPU密集型还是IO密集型,是否有其他任务在同时运行等。

针对CPU密集型的任务:线程池大小应接近于可用核数;
针对IO密集型的任务:线程池可以设置得更大些。




写入时复制


CopyOnWriteArrayList

CopyOnWriteArrayList 使用了保护性复制的策略。它并不是在遍历列表前进行复制,而是在列表被修改时进行,已经投入使用的迭代器会使用当时的旧副本。

比如改变某个元素的值时。
这里写图片描述




阻塞队列


场景:

经典模式——生产者-消费者(producer-consumer)模式

在于生产者和消费者可能不会(几乎肯定不会)保持相同的速度,那么采用阻塞队列,阻塞队列只允许生产者的速度在一定程度上超过消费者的速度,但不会超过很多。


ArrayBlockingQueue

ArrayBlockingQueue 是一个并发队列,适合实现生产者-消费者模式。其提供了高校的并发方法put()take() ,这些方法会在必要时阻塞:当时一个空队列调用take() 时,程序会阻塞直至队列变成非空;当对一个满队列调用put() 时,程序会阻塞直到队列有足够空间。

仿写阻塞队列。




在想想


  1. 阅读ForkJoinPool的文档——fork/join框架与线程池有什么区别?分别适用于什么场景?
  2. 什么是work-stealing?它适用于什么场景?如何用java.util.concurrent包提供的工具实现work-stealing?
  3. CountDownLatch和CyclicBarrier有什么区别?分别适用于什么场景?
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值