Table of contents
1. Introduction to SynchronousQueue
1.2 Source code analysis (TODO)
2. Introduction to Priority Blocking Queue
2.1 PriorityBlockingQueue combat
2.2 Source code analysis (TODO)
3. Introduction to LinkedTransferQueue
5. How to choose a suitable blocking queue
1. Introduction to SynchronousQueue
synchronousQueue is a blocking queue without data buffering. It is applied in newCachedThreadPool. Its size is 0. Every time data fetching needs to block the thread, and storing data also needs to block the thread.
By default, the unfair lock is implemented using the stack structure at the bottom layer, and the fair lock is implemented using the queue structure.
The underlying locking uses the form of CAS + spin (512 times by default) + (park/unpark) to guarantee performance.
1.1 synchronousQueue combat
Two producers and two consumers: Last-in-first-out occurs. Conforms to the unfair lock feature, and the bottom layer is implemented using the stack structure.
import java.util.concurrent.SynchronousQueue;
public class SynchronousQueueTest {
//定义一个synchronousQueue
private final static SynchronousQueue synchronousQueue = new SynchronousQueue();
public static void main(String[] args) throws Exception{
//模拟消费者取数据
new Thread(()->{
try {
synchronousQueue.take();
System.out.println(Thread.currentThread().getName()+"取数据");
} catch (InterruptedException e) {
e.printStackTrace();
}
},"consumer1").start();
new Thread(()->{
try {
synchronousQueue.take();
System.out.println(Thread.currentThread().getName()+"取数据");
} catch (InterruptedException e) {
e.printStackTrace();
}
},"consumer2").start();
//模拟生产者放数据
new Thread(()->{
try {
synchronousQueue.put(1);
System.out.println(Thread.currentThread().getName()+"生产数据");
} catch (InterruptedException e) {
e.printStackTrace();
}
},"producer1").start();
new Thread(()->{
try {
synchronousQueue.put(1);
System.out.println(Thread.currentThread().getName()+"生产数据");
} catch (InterruptedException e) {
e.printStackTrace();
}
},"producer2").start();
}
}
1.2 Source code analysis (TODO)
focus point:
1. Consumer enqueue blocking and CAS spin
2. The producer goes out of the queue and wakes up
3. put and take methods
2. Introduction to Priority Blocking Queue
PriorityBlockingQueue is an unbounded array-based priority blocking queue. The default array length is 11, but it can be expanded wirelessly until the resources are exhausted.
The data will be sorted in ascending order after being stored.
The queue defaults to the highest priority first out.
Application Scenario: VIP Priority Purchase
How to design a priority queue?
PriorityBlockingQueue uses the idea of big top heap and small top heap, big top heap: the value of the parent element is always greater than that of the child element. Small top heap: The value of the parent element is always smaller than the child element.
2.1 PriorityBlockingQueue combat
PriorityBlockingQueue gets data and sorts the stored data
import java.util.Random;
import java.util.concurrent.PriorityBlockingQueue;
public class PriorityBlockingQueueTest {
//定义一个初始容量为3的队列,队列会自动扩容
private static PriorityBlockingQueue priorityBlockingQueue = new PriorityBlockingQueue(3);
public static void main(String[] args) throws InterruptedException {
//存5个数据
System.out.println("存数据");
for(int i=0;i<5;i++){
Random random = new Random();
int j = random.nextInt(100);
System.out.print(j+" ");
priorityBlockingQueue.put(j);
}
//取5个数据
System.out.println("");
System.out.println("取数据");
for(int i=0;i<5;i++){
System.out.print(priorityBlockingQueue.take()+" ");
}
}
}
2.2 Source code analysis (TODO)
focus point:
1. Modified constants: maximum number, reentrant lock, condition queue condition
2. put and take methods (the code of the small top heap)
3. Introduction to LinkedTransferQueue
LinkedTransferQueue is an unbounded blocking queue implemented by a linked list. Use CAS+spin method to lock. It is a combination of synchronousQueue and linkedBlockingQueue, both of which can be implemented.
The put method does not block.
The transfer will block, judge the blocking method, and see if the method throws an interrupt exception.
4. Introduction to DelayQueue
DelayQueue is an unbounded blocking queue implemented by a priority queue, which can achieve the effect of delayed closing.
Application scenarios: order timeout closing, asynchronous SMS notification, closing idle connections, caching, task timeout, etc.
lock: reentrantLock guaranteed
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.DelayQueue;
import java.util.concurrent.Delayed;
import java.util.concurrent.TimeUnit;
public class DelayQueueTest {
public static void main(String[] args) throws InterruptedException {
//定义一个delayQueue
BlockingQueue<DelayedObject> delayeds = new DelayQueue<>();
delayeds.put(new DelayedObject("A",1000 * 10));
delayeds.put(new DelayedObject("B",4000 * 10));
delayeds.put(new DelayedObject("C",3000 * 10));
delayeds.put(new DelayedObject("D",2000 * 10));
//取出元素
System.out.println(delayeds.take());
System.out.println(delayeds.take());
System.out.println(delayeds.take());
System.out.println(delayeds.take());
}
}
class DelayedObject implements Delayed{
private String name;
private long delayTime;
public DelayedObject(String name,long delayTime) {
this.name = name;
this.delayTime = System.currentTimeMillis() + delayTime;
}
@Override
public long getDelay(TimeUnit unit) {
return 0;
}
@Override
public int compareTo(Delayed o) {
return 0;
}
@Override
public String toString() {
Date date = new Date(delayTime);
SimpleDateFormat sd = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
return "\nDelayObject:{"
+ "name=" + name
+ ", time=" + sd.format(date)
+ "}";
}
}
4.1 Source code analysis
1. put and take methods
5. How to choose a suitable blocking queue
Five indicators:
1. Function
2. Capacity: Fixed capacity ( ArrayBlockingQueue ) unlimited capacity ( LinkedBlockingQueue ) no capacity ( SynchronousQueue ) DelayQueue capacity (Integer.MAX_VALUE)
3. Can it be expanded?
No need to expand ( ArrayBlockingQueue ) Need to expand ( PriorityBlockingQueue )
4. Memory structure
Array ( ArrayBlockingQueue ) linked list ( LinkedBlockingQueue )
5. Performance
LinkedBlockingQueue (two locks)
ArrayBlockingQueue (a lock)
SynchronousQueue (direct delivery)