高并发编程-队列-BlockingQueue-SynchronousQueue
高并发编程-队列-BlockingQueue-SynchronousQueue
一、SynchronousQueue简介
SynchronousQueue 也是继承了BlockingQueue,它是没有缓存区域的队列,一个生产者线程的put操作必须等待消费者线程的take操作

如上图所示,缓存区域的容量为0,没有地方可以暂存元素。所以每次在获取数据的时候都要先阻塞,等有数据放入才唤醒。同理当每次放入数据时候,也是先阻塞,直到有线程来获取数据才唤醒。SynchronousQueue直接把数据从生产者给到消费者,不需要中间转存。
二、应用场景
SynchronousQueue适合传递性的交换工作场景,生产者线程和消费者线程同步传递信息、事件、任务。
Executors.newCachedThreadPool()线程池就使用了SynchronousQueue,比如我们不能确定生产者的线程数量,这时候我们为每一位生产者线程匹配一个消费者线程,请求就会被很快处理掉,这样的效率也很高。
三、SynchronousQueue的使用
//定义同步队列 BlockingQueue<Integer> synchronousQueue = new SynchronousQueue<>();
| 特点:没有数据缓存的BlockingQueue,容量为0,是多个线程的交换媒介,不会给队列中的元素存储空间 |
| 数据结构:链表结构。 |
| 数据走向:先有take,后有put,现有消费者Thread1访问,此时队列为空,创建node节点入队。第二个消费线程访问Thread2,继续入队,第三个生产者线程访问,携带数据date,不进入队列,直接将携带的数据交给队 首的消费者,唤醒队首元素。反之原理也一样 |
| 锁方式:CAS+自旋,这个锁方式没有阻塞 |
| 阻塞方式:自选一定数量后,采用LockSupport.park() |
| 过程:线程访问阻塞队列,判断队尾节点和栈顶点的node与当前入队方式是否相同,相同则构造节点Node入队,并阻塞当前线程,元素date和线程给Node属性,不相同元素data放回数据线程,队首栈顶唤醒出队 |
| 公平模式:transferQueue FIFO |
| 非公平模式:transferStack FILO |

浙公网安备 33010602011771号