In the last chapter we wrote ourselves a blocking queue in Java and we wrote an initial blocking queue. Look back in a few days. Yeah, I think I see something wrong. Tried to change it.

Problems with the original queue implementation

We say queues, but what are the characteristics of queues? First in, first out! In the previous version, we used the size value, which is the last position value, to exit the queue. So think about it, are we in a queue? This is the stack. That’s problem number one. And we know that the underlying implementation of an ArrayList is actually an array, so why don’t I just use an array? I don’t really use lists. So this is the second place that can be optimized. In the first version, in order to run properly, I set the initial value of size to -1. I can’t stand it. No, I need to optimize this area as well. Well, let’s optimize those three.

Optimize the problem ArrayList

It’s actually quite simple, changing an ArrayList to an array Object[]. Use Object[IDx] instead of add and get.

Object[] objects = new Object[10];
objects[size] = t;
t = objects.[size];
Copy the code

Optimize out and in teams

The nature of a queue should be a first-in, first-out data structure. There are two IDX’s instead, one is the join index, one is the out index.

int enqIdx = 0;// Join the team index number
int deqIdx = 0;// Queue index number
Copy the code

There is a problem with restarting the index count when it reaches the size of our array.

if((enqIdx+1)==objects.length){
    enqIdx=0;
}
if((deqIdx+1)==objects.length){
    deqIdx=0;
}
Copy the code

Start code


import java.util.Random;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class Item15_Lock_Condition {

    public static void main(String[] args) throws InterruptedException {

        BlockedQueue blockedQueue = new BlockedQueue();


        int i = 0, j = 0;
        while (i++ < 30) {
            Thread thread = new Thread("producer-" + i) {
                @Override
                public void run(a) {
                    while (true) {
                        System.out.println(this.getName() + ", production number :" + blockedQueue.enq(new Random().nextInt(10)));
                        try {
                            Thread.sleep(1000 * new Random().nextInt(10));
                        } catch(InterruptedException e) { e.printStackTrace(); }}}}; thread.start(); }while (j++ < 30) {
            Thread thread1 = new Thread("consumer-" + j) {
                @Override
                public void run(a) {
                    while (true) {
                        System.out.println(this.getName() + ", consumption figures :" + blockedQueue.deq());
                        try {
                            Thread.sleep(1000 * new Random().nextInt(10));
                        } catch(InterruptedException e) { e.printStackTrace(); }}}}; thread1.start(); }while (true) {
            Thread.sleep(1000 * 60 * 60); }}}class BlockedQueue {
    final Lock lock = new ReentrantLock();
    Object[] objects = new Object[10];
    int size = 0;// Capacity value, calculated from 0.
    int enqIdx = 0;// Join the team index number
    int deqIdx = 0;// Queue index number
    // Check if it is full
    Condition notFull = lock.newCondition();
    // Check whether it is empty
    Condition notEmpty = lock.newCondition();


    / / team
    Object enq(Object t) {
        lock.lock();
        try {
            // Check whether the queue is full
            while (size == objects.length) {
                System.out.println("Sorry, full!!");
                notFull.await();
            }
            objects[deqIdx] = t;
            // If the current position is the last, we will start from 0 next time
            if ((deqIdx + 1) == objects.length) {
                deqIdx = 0;
            }
            size++;
            notEmpty.signal();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
        return t;
    }

    / / out of the team
    Object deq(a) {
        lock.lock();

        Object t = null;
        try {
            while (size == 0) {
                System.out.println("Sorry, it's empty...");
                notEmpty.await();
            }
            t = objects[deqIdx];
            // If the current index is the last one and is already out of the queue, we will start the calculation from 0 next time
            if ((deqIdx + 1) == objects.length) {
                deqIdx = 0;
            }
            size--;
            notFull.signal();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
        returnt; }}Copy the code

Well, it looks a bit like that. It doesn’t feel like it did before. After all, this version is a serious fifO queue. And the hated count from -1 has been changed. Sometimes it’s nice to add a few pointer indexes.