Semaphore
Semaphore 可以允许多个线程访问一个临界区。
应用:实现线程池
CountDownLatch
应用:
业务原始状态:一个线程执行查询订单,查询派送单,对比差异,写入数据库
优化后:多线程并发执行:一个线程查询订单,一个线程查询派送单,一个线程对比差异并写入数据库
问题:线程执行顺序问题,第三个线程必须等其他两个线程把两种订单信息查询出来才可以对比差异,所以使用CountDownLatch,在那两个线程的执行方法体内调用CountDownLatch的countDown()方法,CountDownLatch调用await()方法进行等待。
进一步优化:如果第二次查询操作不需要等待第一次对比差异并写入数据库的操作就可以执行呢,速度又会更快,那么实现一个生产消费者模型就可以,那两个查询订单的线程为生产者,第三个线程为消费者。
具体实现:
并发容器
ConcurrentHashMap和ConcurrentSkipListMap
如果对于ConcurrentHashMap的并发度还不满意就可以考虑使用ConcurrentSkipListMap,因为ConcurrentSkipListMap的时间复杂度为O(logn),且理论上和并发度没有关系。
四类:
单端阻塞:使用最多
- ArrayBlockingQueue:内部持有数组,生产和消费时共用一把锁
- LinkedBlockingQueue:内部持有链表,生产和消费各用一把锁
- SynchronousQueue:内部不持有队列,生产者的生产操作必须等待消费者的消费操作
- LinkedTransferQueue:融合LinkedBlockingQueue和SynchronousQueue,性能更好
- PriorityBlockingQueue:支持按照优先级出队,存储的对象必须实现Comparable接口,通过里面的compare方法确定优先级
- DelayQueue:支持延时出队,应用:缓存系统的设计,轮询取数,一旦有数可以取出说明失效时间到了
单端非阻塞:ConcurrentLinkedQueue
双端阻塞:LinkedBlockingDeque
双端非阻塞:ConcurrentLinkedDeque
但是在实际使用中一般使用有界队列:ArrayBlockingQueue和LinkedBlockingQueue,因为无界队列容易有OOM隐患。
Original: https://www.cnblogs.com/zz01/p/16612389.html
Author: 山野村夫01
Title: 并发编程学习
原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/621904/
转载文章受原作者版权保护。转载请注明原作者出处!