概述
实现我上一篇博客中提到的
实际上,就是用synchronized代码块解决线程安全问题,以及利用wait()、notify()实现线程阻塞、唤醒。
实现
pollV3()
private Object lockBySynchronized=new Object();
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()
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(); // 唤醒要出队元素的线程 执行出队元素的逻辑}}
测试用例
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();}
测试用例输出
最后
这篇博客应该就是基于数组实现队列的最后一篇了吧。
好了,如果对你有帮助的话,欢迎点个免费的赞哦。