Synchronousqueue details

Synchronousqueue details

brief introduction

Synchronous queue is a kind of BlockingQueue, so synchronous queue is thread safe. The difference between synchronous queue and other blockingqueues is that the capacity of synchronous queue is 0. That is, the synchronousqueue does not store any elements.

That is, each insert operation of the synchronousqueue must wait for other linear remove operations. Each remove operation must also wait for the insert operation of other threads.

This feature reminds us of exchange. Unlike exchange, you can pass the same object in two threads using synchronous queue. One thread puts the object and the other thread takes the object.

Examples

Let's take an example of passing objects in multithreading. Let's take the example of producer consumer. We create an object in the producer, and we take out the object in the consumer. Let's take a look at what to do with 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();
    }

In the above example, we use atomicreference to store the objects to be passed, and define a countdownlatch with a model quantity of 1.

In producer, we store objects and count down.

In the consumer, we wait, and then take out the object.

Output results:

[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

You can see that the same object is passed in and output.

The above example can also be rewritten with 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 {}",TimeUnit.MILLISECONDS);
        executor.shutdown();
    }

In the above example, if we use synchronous queue, we can avoid manual synchronization and additional storage.

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>