课程名称:笑傲Java面试 剖析大厂高频面试真题 秒变offer收割机
课程章节:第5章 并发提高篇
主讲老师:求老仙
课程内容:
第5章 并发提高篇
课程收获:
并发的数据结构blockQueue
在实际工作中,使用锁的概率并不大,原因是Java已经帮我们封装了锁的操作,就在这些数据结构中,比如:队列《链表阻塞队列,同步队列》
问题1)队列,实现生产者和消费者模型
构造批量处理任务,构造线程池,都是使用队列。
放元素和取出元素:
Add**/remove:如果队列满了,add会抛出异常,remove如果队列空了会抛出异常,所以一般不用。**
Offer/poll: 队列满offer会返回false,不阻塞,null,如果队列空poll会返回。
Put/take:阻塞版本,take取出的不会是null,会响应中断
问题2)生产者,消费者问题,使用有界队列?
生产者和消费者问题,又称为有界缓冲区问题
public static void main(String[] argv) {
BlockingQueue queue;
//queue = new ArrayBlockingQueue(10);
// 链表可以是无限队列,或者有限队列
//queue = new LinkedBlockingQueue();
// 双向队列
//queue = new LinkedBlockingDeque<>();
//带优先级的队列,从队列中取,当前队列值最小的元素
//queue = new PriorityBlockingQueue<>();
//queue = new LinkedTransferQueue();
queue = new SynchronousQueue<>();
//queue = new DelayQueue<>();
// Producer
for(int i = 0; i < 100; i++) {
new Thread(() -> {
try {
queue.put((int) (Math.random() * 1000));
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
}
// Consumer
for(int i = 0; i < 10; i++) {
new Thread(() -> {
while(true) {
Integer x = null;
try {
x = queue.take();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(“Receive:” + x);
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
}
}
问题3)队列除了处理生产者消费者,还线程安全?
问题4)队列的使用场景?
链表阻塞队列 LinkedBlockingDeque》场景2:undo操作,就需要使用双向队列,deque表示双向队列
从一头插入,可以从两头****删除
场景3:优先级队列,堆的使用场景?优先级队列?
因为堆的元素要比较大小,所以要实现comparator,让元素可比较。
PriorityBlockingQueue是优先级****阻塞队列,在多线程场景下实现优先级队列,要是实现Comparator方法,
PriorityQueue是优先级****队列,在单线程场景下使用,也要实现Comparator方法,
PriorityBlockingQueue也是基于最小二叉堆实现,使用基于CAS实现的自旋锁来控制队列的动态扩容,保证了扩容操作不会阻塞take操作的执行。
PriorityBlockingQueue有四个构造方法:
// 默认的构造方法,该方法会调用this(DEFAULT_INITIAL_CAPACITY, null),即默认的容量是11
public PriorityBlockingQueue()
// 根据initialCapacity来设置队列的初始容量
public PriorityBlockingQueue(int initialCapacity)
// 根据initialCapacity来设置队列的初始容量,并根据comparator对象来对数据进行排序
public PriorityBlockingQueue(int initialCapacity, Comparator<? super E> comparator)
// 根据集合来创建队列
public PriorityBlockingQueue(Collection<? extends E> c)
DelayQueue延迟队列:场景4:发大量的券,分批量****发,系统资源不能一次承受太大请求,只能每秒发多少张,将海量的任务,批量处理
-
发优惠券
-
生成订单发短信
-
大量延迟重试
- 线程池,是一种设计模式:
注意:
1,延迟队列实际上也是个优先级队列,时间越小的越优先执行,时间为0表示应该执行,优先级是按照时间来进行比较的,所以也需要实现compareTo比较方法。