java并发包提供哪些并发工具类?
我们通常所说的并发包就是java.util.concurrent及其子包,集中了java并发的各种工具类,主要包括以下几个方面:
- 提供了比synchronized更加高级的同步结构,包括CountDownLatch、CyclicBarrier、Semaphore等,可以实现更加丰富的多线程操作,比如利用Semaphore作为资源控制器,可以控制同时工作的线程数量。
- 各种线程安全的容器,比如ConcurrentHashMap、ConcurrenSkipListMap还有线程安全的动态数组CopyOnWriteArrayList。
- 各种并发队列实现,如各种 BlockedQueue 实现,比较典型的ArrayBlockingQueue、SynchorousQueue。
- 强大的Executor框架,可以创建各种不同类型的线程池,来调度任务运行。
我们进行多线程编程的目的:
- 利用多线程提高程序的扩展能力,已达到业务对吞吐量的要求。
- 协调线程间调度、交互,以完成业务逻辑。
- 线程间传递数据和状态,这同样是实现业务逻辑的需求。
并发包下同步结构:
- CountDownLatch:允许一个或多个线程等待某些操作完成
- CyclicBarrier:一种辅助性的同步结构,允许多个线程等待到达某个屏障。
- Semaphore:Java版本的信号量实现。
Java提供典型的信号量实现,它通过控制一定数量的允许的方式,来达到限制通用资源访问的目的。
CountDownLatch和CyclicBarrier的区别
- CountDownLatch是不可重置的,所以无法重用,而CyclicBarrier没有这种限制。
- CountDownLatch的基本操作组合是countDown/await。调用await的线程阻塞等待countdown足够的次数,不管是在单线程或者多线程里countDown,只要次数足够即可。
- CyclicBarrier的基本操作组合就是await,当所有的parties都调用await时,才会继续进行任务,并且自动进行重置。
并发包提供的线程安全的map、list和set:
如果我们侧重于Map放入或者获取的速度,而不在乎顺序,大多推荐使用ConcurrentHashMap,反之推荐使用ConcurrentSkipListMap。如果需要对大量的数据进行非常频繁的修改,ConcurrentSkipListMap也可能展现出优势。
两个CopyOnWrite容器,CopyOnWriteArraySet是通过包装了CopyOnWriteArrayList来实现的。CopyOnWrite的原理是,任何修改操作,比如add、remove、set都会拷贝原数组,修改后的数组替换原来的数组,通过这种防御性的方式来实现另类的线程安全。所以这种结构比较适合读多写少的操作,不然修改的开销还是比较明显的。