• SynchronousQueue简介


    一、介绍:

    • SynchronousQueue 是一个具有零容量的队列,它不保存任何元素,它的主要作用是在线程之间传递数据。
    • 当生产者线程尝试将数据放入 SynchronousQueue 时,它会阻塞,直到有一个消费者线程来获取这个数据。
    • 同样地,当消费者线程尝试从 SynchronousQueue 获取数据时,它也会阻塞,直到有一个生产者线程将数据放入队列。

    二、使用demo:

    public class Test {
    
        public static void main(String[] args) {
    
            Logger log = LoggerFactory.getLogger(Test.class);
    
    
            SynchronousQueue<Integer> integers = new SynchronousQueue<>();
            new Thread(() -> {
                try {
                    log.info("putting {} ", 1);
                    integers.put(1);
                    log.info("{} putted...", 1);
                    log.info("putting...{} ", 2);
                    integers.put(2);
                    log.info("{} putted...", 2);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }, "t1").start();
    
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
    
            new Thread(() -> {
                try {
                    log.info("taking {}", 1);
                    integers.take();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }, "t2").start();
    
       /*     try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
    
            new Thread(() -> {
                try {
                    log.info("taking {}", 2);
                    integers.take();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }, "t3").start();*/
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52

    可以得出结论:如果没有消费者来消费, 2 是不能放入 SynchronousQueue 队列中的;
    将注释的代码打开,则 2 可以正常放入 !!!
    在这里插入图片描述

    三、死锁的场景

    需要注意的是,SynchronousQueue 的使用需要谨慎,因为它非常容易导致死锁,如果没有恰当地设计和同步生产者和消费者线程,可能会造成程序无法继续执行。因此,在使用 SynchronousQueue 时要注意线程同步和错误处理。

    以下是一个 SynchronousQueue 可能导致死锁的示例情况:

    public class SynchronousQueueDeadlockDemo {
        public static void main(String[] args) {
            final SynchronousQueue<Integer> queue = new SynchronousQueue<>();
    
            Thread thread1 = new Thread(() -> {
                try {
                    // 线程1尝试将数据放入队列
                    int data = 42;
                    queue.put(data);
                    System.out.println("线程1放入数据:" + data);
    
                    // 接着,线程1尝试从队列中获取数据,但此时没有其他线程来获取
                    int result = queue.take();
                    System.out.println("线程1获取数据:" + result);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            });
    
            Thread thread2 = new Thread(() -> {
                try {
    
                    // 接着,线程2尝试将数据放入队列,但此时没有其他线程来获取
                    int result = 100;
                    queue.put(result);
                    System.out.println("线程2放入数据:" + result);
    
                    // 线程2尝试从队列中获取数据,但此时没有数据可用
                    int data = queue.take();
                    System.out.println("线程2获取数据:" + data);
    
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            });
    
            thread1.start();
            thread2.start();
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41

    可以看到线程1,线程2 都尝试向SynchronousQueue中放入元素,都阻塞在这里 。
    在这里插入图片描述

  • 相关阅读:
    【算法练习Day29】柠檬水找零&&根据身高重建队列&&用最少数量的箭引爆气球
    IB-MYP课程知道为什么这么难吗?从课程讲起
    Web Api的参数传递建议
    【数据分享】2005-2022年全国民航机场客货吞吐量和起降架次数据
    深入理解蓝牙BLE之“扩展广播”
    Docker 容器生命周期:创建、启动、暂停与停止
    Redis--模糊查询--方法/实例
    11-1java集合框架的概述
    bootz 启动 kernel
    【金融项目】尚融宝项目(十三)
  • 原文地址:https://blog.csdn.net/hc1285653662/article/details/133607411