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.