SynchronousQueue详解「建议收藏」

SynchronousQueue详解「建议收藏」SynchronousQueue是BlockingQueue的一种,所以SynchronousQueue是线程安全的。SynchronousQueue和其他的BlockingQueue不同的是SynchronousQueue的capacity是0。即SynchronousQueue不存储任何元素。也就是说SynchronousQueue的每一次insert操作,必须等待其他线性的remove操作。而每一个remove操作也必须等待其他线程的insert操作。这种特性可以让我们想起了Exchanger

大家好,又见面了,我是你们的朋友全栈君。

文章目录

SynchronousQueue详解

简介

SynchronousQueue是BlockingQueue的一种,所以SynchronousQueue是线程安全的。SynchronousQueue和其他的BlockingQueue不同的是SynchronousQueue的capacity是0。即SynchronousQueue不存储任何元素。

也就是说SynchronousQueue的每一次insert操作,必须等待其他线性的remove操作。而每一个remove操作也必须等待其他线程的insert操作。

这种特性可以让我们想起了Exchanger。和Exchanger不同的是,使用SynchronousQueue可以在两个线程中传递同一个对象。一个线程放对象,另外一个线程取对象。

举例说明

我们举一个多线程中传递对象的例子。还是举生产者消费者的例子,在生产者中我们创建一个对象,在消费者中我们取出这个对象。先看一下用CountDownLatch该怎么做:

    @Test
    public void useCountdownLatch() throws InterruptedException { 
   
        ExecutorService executor = Executors.newFixedThreadPool(2);
        AtomicReference<Object> atomicReference= new AtomicReference<>();
        CountDownLatch countDownLatch = new CountDownLatch(1);

        Runnable producer = () -> { 
   
            Object object=new Object();
            atomicReference.set(object);
            log.info("produced {}",object);
            countDownLatch.countDown();
        };

        Runnable consumer = () -> { 
   
            try { 
   
                countDownLatch.await();
                Object object = atomicReference.get();
                log.info("consumed {}",object);
            } catch (InterruptedException ex) { 
   
                log.error(ex.getMessage(),ex);
            }
        };

        executor.submit(producer);
        executor.submit(consumer);

        executor.awaitTermination(50000, TimeUnit.MILLISECONDS);
        executor.shutdown();
    }

上例中,我们使用AtomicReference来存储要传递的对象,并且定义了一个型号量为1的CountDownLatch。

在producer中,我们存储对象,并且countDown。

在consumer中,我们await,然后取出对象。

输出结果:

[pool-1-thread-1] INFO com.flydean.SynchronousQueueUsage - produced java.lang.Object@683d1b4b
[pool-1-thread-2] INFO com.flydean.SynchronousQueueUsage - consumed java.lang.Object@683d1b4b

可以看到传入和输出了同一个对象。

上面的例子我们也可以用SynchronousQueue来改写:

    @Test
    public void useSynchronousQueue() throws InterruptedException { 
   
        ExecutorService executor = Executors.newFixedThreadPool(2);
        SynchronousQueue<Object> synchronousQueue=new SynchronousQueue<>();

        Runnable producer = () -> { 
   
            Object object=new Object();
            try { 
   
                synchronousQueue.put(object);
            } catch (InterruptedException ex) { 
   
                log.error(ex.getMessage(),ex);
            }
            log.info("produced {}",object);
        };

        Runnable consumer = () -> { 
   
            try { 
   
                Object object = synchronousQueue.take();
                log.info("consumed {}",object);
            } catch (InterruptedException ex) { 
   
                log.error(ex.getMessage(),ex);
            }
        };

        executor.submit(producer);
        executor.submit(consumer);

        executor.awaitTermination(50000, TimeUnit.MILLISECONDS);
        executor.shutdown();
    }

上面的例子中,如果我们使用synchronousQueue,则可以不用手动同步,也不需要额外的存储。

总结

如果我们需要在代码中用到这种线程中传递对象的情况,那么使用synchronousQueue吧。

本文的例子https://github.com/ddean2009/learn-java-collections

更多精彩内容且看:

欢迎关注我的公众号:程序那些事,更多精彩等着您!
更多内容请访问 www.flydean.com

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/152133.html原文链接:https://javaforall.net

赞 (0)
全栈程序员-站长的头像全栈程序员-站长

相关推荐

  • Cocos2d-x教程(30)-3.x版本号物理引擎的使用

    Cocos2d-x教程(30)-3.x版本号物理引擎的使用

    2021年12月7日
  • arrays.sort排序_js数组排序方法sort

    arrays.sort排序_js数组排序方法sortArrays.sort默认是升序,如果我们需要降序排列数组?Arrays.sort(distances);——升序Arrays.sort(distances,Collections.reverseOrder());——降序再说说Collections集合类,用来排序集合的Collections.sort(list)——升序Collections.reverse(list…

    2022年8月12日
  • Vue 子组件调用父组件的属性,方法「建议收藏」

    Vue 子组件调用父组件的属性,方法「建议收藏」一、子组件调用父组件的方法子组件里用$emit向父组件触发一个事件,父组件监听这个事件就行了//父组件<template><div><label>我是父组件</label><child@fatherMethod=”test”></child>&…

    2022年9月27日
  • 2020熔化焊接与热切割作业模拟考试_熔化焊接与热切割考试题与答案

    2020熔化焊接与热切割作业模拟考试_熔化焊接与热切割考试题与答案题库来源:安全生产模拟考试一点通公众号小程序2022年熔化焊接与热切割考试题系熔化焊接与热切割判断题上机考试练习题!2022熔化焊接与热切割考试题库及模拟考试根据熔化焊接与热切割新版考试题库。熔化焊接与热切割全部考试题库随时根据安全生产模拟考试一点通上模拟考试。1、【单选题】CO2气体保护内圆孔自动立堆焊机不能用于修复()。(C)A、机车摇连杆孔B、机车车轮轮毂孔C、火车车轮轮缘2、【单选题】不属于低真空电子束焊的应用的是()。(B)A、变速箱B、导弹…

    2022年9月4日
  • 一些基本数字图像处理算法

    一些基本数字图像处理算法一些基本数字图像处理算法所有的图像算法都在DIPAlgorithm类中,并且所有算法都为抽象成员函数。我已经按照java注释规范为所有方法添加使用说明注释,具体实现可见于DIPAlgorithm.java,这里只做算法说明。1图像扭曲模仿PS的扭曲功能,通过建立一个三角形映射网格实现对图像的扭曲。如上图,一共设置了45个控制点围成74个三角形网格扭曲即形变处理其实是寻找一个函数,以所…

    2022年5月13日
  • android游戏开发引擎_android主题引擎

    android游戏开发引擎_android主题引擎随着Android系统的使用越来越广泛,了解一下Android平台下的游戏引擎就非常有必要。而同时因为基于Intelx86的移动设备越来越多,我也非常关注支持x86的移动游戏引擎。然而就目前为止游戏引擎的数量已经非常之多,每个引擎都有不同的特征、价格、成熟度等。通过一些调研之后,我发现有非常多的游戏引擎可用于开发运行在android移动设备端的游戏,其中有些还支持x86系统,另外还有些通过简单的

    2022年10月22日

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号