概述
实现我上一篇博客中提到的
实际上,就是用synchronized代码块解决线程安全问题,以及利用wait()、notify()实现线程阻塞、唤醒。
实现
pollV3()
java
private Object lockBySynchronized=new Object();
java
public int pollV3() {
synchronized (lockBySynchronized){ //synchronized代码块解决线程安全问题
while (tail == 0) { // 没有元素
try {
lockBySynchronized.wait(); // 让出队元素的线程阻塞 直到被其他线程唤醒
} catch (InterruptedException e) {
log.info("等待队列有元素的过程中被打断",e);
}
}
int polled = arr[0]; // 队头元素
log.info("出队成功,队头元素为:{}",polled);
System.arraycopy(arr,1,arr,0,tail-1);
tail--; // 出队后 tail往前移动一位
lockBySynchronized.notify();
return polled;
}
}
offerV3()
java
public void offerV3(int value) {
synchronized (lockBySynchronized){
while (tail == capacity) {
try {
lockBySynchronized.wait(); // 当前线程阻塞直到被唤醒或打断(其他线程调用signal方法,并且唤醒的线程刚好是该线程或其他线程调用signalAll方法) 关联该condition的锁会被自动释放
} catch (InterruptedException e) {
log.info("被打断了...");
}
}
arr[tail] = value;
log.info("元素 {}入队成功",value);
tail++;
lockBySynchronized.notify(); // 唤醒要出队元素的线程 执行出队元素的逻辑
}
}
测试用例
java
public static void main(String[] args) throws InterruptedException {
ArrayQueue queue = new ArrayQueue(3);
Thread t1 = new Thread(() -> {
queue.offerV3(1);
queue.offerV3(2);
}, "t1");
Thread t2 = new Thread(() -> {
queue.offerV3(3);
}, "t2");
Thread t3 = new Thread(() -> {
queue.offerV3(4);
}, "t3");
t1.start();
t2.start();
t3.start();
//25ms以后执行一次出队操作 由于发生了出队操作 入队操作就应该可以成功
log.info("5s以后执行一次出队操作");
TimeUnit.SECONDS.sleep(5);
int polled = queue.pollV3();
log.info("出队的元素:{}",polled);
// t1 t2 t3 3个线程的代码都执行完后再遍历队列
t1.join();
t2.join();
t3.join();
queue.print();
}
测试用例输出

最后
这篇博客应该就是基于数组实现队列的最后一篇了吧。
好了,如果对你有帮助的话,欢迎点个免费的赞哦。