Java in-depth learning: concurrent queues

Keywords: Java JDK

Concurrent queue:

In concurrent queues, JDK has two implementations:

Concurrent LinkedQueue: Non-blocking Queue

BlockingQueue: Blocking Queue

 

Differences between blocking and non-blocking queues:

When a blocking queue is included in a queue operation, if it exceeds the total number of queues, it will wait at this time; when a queue is empty, it will also wait.

No obstruction, no matter what.

Non-blocking is more efficient, but blocking is more widely used.

The advantage of blocking queues is that they can prevent queue containers from overflowing and losing.

 

Non-blocking queues:

public class QueueDemo {
    public static void main(String[] args) {
        ConcurrentLinkedQueue<String> concurrentLinkedQueue = new ConcurrentLinkedQueue<>();
        concurrentLinkedQueue.offer("Zhang San");
        concurrentLinkedQueue.offer("Li Si");
        concurrentLinkedQueue.offer("Wang Wu");
        for (int i = 0; i < 4; i++) {
            System.out.println(concurrentLinkedQueue.poll());
        }
    }
}

Print as follows:

Zhang San
Li Si
Wang Wu
null

 

Blocking queues (important): total number of queues that need to be initialized

public class QueueDemo {
    public static void main(String[] args) throws InterruptedException {
        BlockingQueue<String> arrayBlockingQueue = new ArrayBlockingQueue<>(3);
        //Adding non-blocking queues
        arrayBlockingQueue.offer("Zhang San");
        arrayBlockingQueue.offer("Li Si");
        arrayBlockingQueue.offer("Wang Wu");
        //Add a blocking queue with a waiting time of 3 s
        arrayBlockingQueue.offer("Zhao Liu",3, TimeUnit.SECONDS);
        System.out.println(arrayBlockingQueue.poll());
        System.out.println(arrayBlockingQueue.poll());
        System.out.println(arrayBlockingQueue.poll());
        System.out.println(arrayBlockingQueue.poll(3,TimeUnit.SECONDS));
    }
}

In this case, wait for 3 seconds to print: Zhang San, Li Si, Wang Wu, and then wait for 3 seconds to print: null.

 

Change the code:

public class QueueDemo {
    public static void main(String[] args) throws InterruptedException {
        BlockingQueue<String> arrayBlockingQueue = new ArrayBlockingQueue<>(3);
        //Adding non-blocking queues
        arrayBlockingQueue.offer("Zhang San");
        arrayBlockingQueue.offer("Li Si");
        System.out.println(arrayBlockingQueue.poll());
        arrayBlockingQueue.offer("Wang Wu");
        //Add a blocking queue with a waiting time of 3 s
        arrayBlockingQueue.offer("Zhao Liu",3, TimeUnit.SECONDS);
        System.out.println(arrayBlockingQueue.poll());
        System.out.println(arrayBlockingQueue.poll());
        System.out.println(arrayBlockingQueue.poll());
        System.out.println(arrayBlockingQueue.poll(3,TimeUnit.SECONDS));
    }
}

In this case, print Zhang San, Li Si, Wang Wu and Zhao Liu immediately, and wait for 3 seconds to print null.

 

Example:

public class QueueDemo {
    public static void main(String[] args) throws InterruptedException {
        BlockingQueue<String> arrayBlockingQueue = new ArrayBlockingQueue<>(3);
        //Adding non-blocking queues
        boolean success1 = arrayBlockingQueue.offer("Zhang San");
        boolean success2 = arrayBlockingQueue.offer("Li Si");
        boolean success3 = arrayBlockingQueue.offer("Wang Wu");
        //Add a blocking queue with a waiting time of 3 s
        boolean success4 = arrayBlockingQueue.offer("Zhao Liu",3, TimeUnit.SECONDS);
        System.out.println(success1);
        System.out.println(success2);
        System.out.println(success3);
        System.out.println(success4);
    }
}

Wait for 3 seconds and print: true, true, false; indicating that Zhao Liu was not listed successfully.

 

Producer consumer example:

The following is a simulation of a producer-consumer example for better understanding:

Producer threads store a queue, consumer threads take a queue. Waiting for wake-up mechanism can be used in multi-threads, where concurrent queues are used.

package org.dreamtech;

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * Producer threads, responsible for adding queues
 */
class ProducerThread implements Runnable {

    private BlockingQueue<String> blockingQueue;

    private volatile boolean FLAG = true;

    private AtomicInteger atomicInteger = new AtomicInteger();

    ProducerThread(BlockingQueue<String> blockingQueue) {
        this.blockingQueue = blockingQueue;
    }

    @Override
    public void run() {
        try {
            System.out.println("---Producer Thread Start Successfully---");
            while (FLAG) {
                String data = atomicInteger.incrementAndGet() + "";
                boolean success = blockingQueue.offer(data, 2, TimeUnit.SECONDS);
                if (success) {
                    System.out.println("---Successful queuing of producers->data:" + data + "---");
                } else {
                    System.out.println("---Producer Input Queue Failure->data:" + data + "---");
                }
                Thread.sleep(1000);
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            System.out.println("---The producer thread has ended---");
        }
    }

    public void stop() {
        this.FLAG = false;
    }

}

/**
 * Consumer threads, responsible for getting queues
 */
class ConsumerThread implements Runnable {

    private BlockingQueue<String> blockingQueue;

    private boolean FLAG = true;

    ConsumerThread(BlockingQueue<String> blockingQueue) {
        this.blockingQueue = blockingQueue;
    }

    @Override
    public void run() {
        try {
            System.out.println("---Successful start of consumer thread---");
            while (FLAG) {
                String data = blockingQueue.poll(2, TimeUnit.SECONDS);
                if (data == null) {
                    System.out.println("---Consumers do not get queue information---");
                    FLAG = false;
                    return;
                }
                System.out.println("---Consumers get queue information->data:" + data + "---");
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            System.out.println("---The consumer thread has ended---");
        }
    }

}

public class Test {
    public static void main(String[] args) {
        try {
            BlockingQueue<String> blockingQueue = new LinkedBlockingQueue<>(10);
            ProducerThread producerThread = new ProducerThread(blockingQueue);
            ConsumerThread consumerThread = new ConsumerThread(blockingQueue);
            Thread producer = new Thread(producerThread);
            Thread consumer = new Thread(consumerThread);
            producer.start();
            consumer.start();
            Thread.sleep(10000);
            producerThread.stop();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

Print as follows:

The consumer thread started successfully.
Producer Threads Start Successfully
The producer succeeded in queuing - > data: 1 - - -
Consumers get queue information - > data: 1 - -
- Producers succeed in queuing - > data: 2 - -
Consumers get queue information - > data: 2
.............................................
Producers succeed in queuing - > data: 9
Consumers get queue information - > data: 9 - -
Producers succeed in queuing - > data: 10
Consumers get queue information - > data: 10
The producer thread is over.
Consumers do not have access to queue information.
The consumer thread is over.

Posted by altexis on Mon, 07 Oct 2019 17:17:14 -0700