并发编程学习
Semaphore
Semaphore 可以允许多个线程访问一个临界区。
应用:实现线程池
CountDownLatch
应用:
业务原始状态:一个线程执行查询订单,查询派送单,对比差异,写入数据库
优化后:多线程并发执行:一个线程查询订单,一个线程查询派送单,一个线程对比差异并写入数据库
问题:线程执行顺序问题,第三个线程必须等其他两个线程把两种订单信息查询出来才可以对比差异,所以使用CountDownLatch,在那两个线程的执行方法体内调用CountDownLatch的countDown()方法,CountDownLatch调用await()方法进行等待。
进一步优化:如果第二次查询操作不需要等待第一次对比差异并写入数据库的操作就可以执行呢,速度又会更快,那么实现一个生产消费者模型就可以,那两个查询订单的线程为生产者,第三个线程为消费者。
具体实现:
-
两个队列:一个对应订单,一个对应派送单,一对一对消费(一对一关系),保证消费不会出错;
-
一个线程查完订单库,一个线程查完派送单库,两个都查完通知第三个线程,但是两个线程查完一次之后还要重复进行操作,就用到了CyclicBarrier同步工具类。
-
CyclicBarrier可自动重置屏障,就可实现上述功能。
并发容器
ConcurrentHashMap和ConcurrentSkipListMap
如果对于ConcurrentHashMap的并发度还不满意就可以考虑使用ConcurrentSkipListMap,因为ConcurrentSkipListMap的时间复杂度为O(logn),且理论上和并发度没有关系。
阻塞队列
四类:
单端阻塞:使用最多
-
ArrayBlockingQueue:内部持有数组,生产和消费时共用一把锁
-
LinkedBlockingQueue:内部持有链表,生产和消费各用一把锁
-
SynchronousQueue:内部不持有队列,生产者的生产操作必须等待消费者的消费操作
-
LinkedTransferQueue:融合LinkedBlockingQueue和SynchronousQueue,性能更好
-
PriorityBlockingQueue:支持按照优先级出队,存储的对象必须实现Comparable接口,通过里面的compare方法确定优先级
-
DelayQueue:支持延时出队,应用:缓存系统的设计,轮询取数,一旦有数可以取出说明失效时间到了
单端非阻塞:ConcurrentLinkedQueue
双端阻塞:LinkedBlockingDeque
双端非阻塞:ConcurrentLinkedDeque