高并发编程-队列-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
posted @ 2021-12-07 14:56  小亲年  阅读(166)  评论(0)    收藏  举报