java多线程系列(九)—ArrayBlockingQueue源码分析详解编程语言
2023-06-13 09:20:44 时间
/** items index for next take, poll, peek or remove */ int takeIndex;
/** items index for next put, offer, or add */ int putIndex;
/** Number of elements in the queue */ int count;
/* * Concurrency control uses the classic two-condition algorithm * found in any textbook. */ /** Main lock guarding all access */ final ReentrantLock lock;
/** Condition for waiting takes */ private final Condition notEmpty;
/** Condition for waiting puts */ private final Condition notFull;
public ArrayBlockingQueue(int capacity, boolean fair) { if (capacity = 0) throw new IllegalArgumentException(); this.items = new Object[capacity]; lock = new ReentrantLock(fair); notEmpty = lock.newCondition(); notFull = lock.newCondition(); }
从源码可以看到,创建一个object数组,然后创建一个公平或非公平锁,然后创建出队条件和入队条件
checkNotNull(e); final ReentrantLock lock = this.lock; lock.lock(); try { if (count == items.length) return false; else { enqueue(e); return true; } } finally { lock.unlock(); } }
private void enqueue(E x) { // assert lock.getHoldCount() == 1; // assert items[putIndex] == null; final Object[] items = this.items; items[putIndex] = x; if (++putIndex == items.length) putIndex = 0; count++; notEmpty.signal(); }
指定时间的offer方法
public boolean offer(E e, long timeout, TimeUnit unit) throws InterruptedException { checkNotNull(e); long nanos = unit.toNanos(timeout); final ReentrantLock lock = this.lock; lock.lockInterruptibly(); try { while (count == items.length) { if (nanos = 0) return false; nanos = notFull.awaitNanos(nanos); } enqueue(e); return true; } finally { lock.unlock(); } }
方法大致和前面的一致,不同的时候是当队列满的时候,会等待一段时间,此时入队条件等待一段时间,一段时间后继续进入循环进行判断队列还满
public boolean add(E e) { return super.add(e); }
else throw new IllegalStateException( Queue full }
执行offer方法,这个时候可以对比上面直接调用offer,offer方法如果入队失败会直接返回false,而add方法会抛出异常
put方法
public void put(E e) throws InterruptedException { checkNotNull(e); final ReentrantLock lock = this.lock; lock.lockInterruptibly(); try { while (count == items.length) notFull.await(); enqueue(e); } finally { lock.unlock(); } }
public E poll() { final ReentrantLock lock = this.lock; lock.lock(); try { return (count == 0) ? null : dequeue(); } finally { lock.unlock(); } }
private E dequeue() { // assert lock.getHoldCount() == 1; // assert items[takeIndex] != null; final Object[] items = this.items; @SuppressWarnings( unchecked ) E x = (E) items[takeIndex]; items[takeIndex] = null; if (++takeIndex == items.length) takeIndex = 0; count--; if (itrs != null) itrs.elementDequeued(); notFull.signal(); return x; }
指定时间的poll方法
public E poll(long timeout, TimeUnit unit) throws InterruptedException { long nanos = unit.toNanos(timeout); final ReentrantLock lock = this.lock; lock.lockInterruptibly(); try { while (count == 0) { if (nanos = 0) return null; nanos = notEmpty.awaitNanos(nanos); } return dequeue(); } finally { lock.unlock(); } }
与offer的指定时间和没有指定时间类似,poll指定时间的方法和没有指定时间的poll思路大致是一样的
当此时队列为空的,为等待一段时间,然后自动唤醒,继续进入循环,直到队列中有元素,然后执行dequeue方法
take方法
public E take() throws InterruptedException { final ReentrantLock lock = this.lock; lock.lockInterruptibly(); try { while (count == 0) notEmpty.await(); return dequeue(); } finally { lock.unlock(); } }
offer(E e, long timeout, TimeUnit unit) 队列满的时候,等待一段时间,释放锁,一段时间后,进入就绪状态
poll(long timeout, TimeUnit unit) 队列为空的时候,等待一段时间,释放锁,一段时候后,进入就绪状态
总体的设计思路,通过一个数组来模拟一个数组,出队和入队都是同步的,也就是同一时间只能有一个入队或者出队操作,然后在入队的时候,如果队列已满的话,根据方法的不同有不同的策略,可以直接返回或者抛出异常,也可以阻塞一段时间,等会在尝试入队,或者直接阻塞,直到有人唤醒。而出队的时候,如果为空可以直接返回,也可以等待一段时间然后再次尝试,也可以阻塞,直到有人唤醒
相关文章
- Java BigDecimal加减乘除运算[通俗易懂]
- excel宏 java,Microsoft Excel宏运行Java程序
- java控制台输入数组_Java控制台输入数组并逆序输出的方法实例
- java笛卡尔积算法_Java 笛卡尔积算法的简单实现
- 【说站】java程序编好了怎么运行
- 【说站】java怎么从键盘输入一个数
- Java重置_java设置定时任务一小时执行一次
- 一文带你深入理解Java多线程与高并发:Atomic类和线程同步新机制
- java长轮询「建议收藏」
- java 数字信封_【Java密码学】使用Bouncy Castle生成数字签名、数字信封
- java prototype是什么,Java设计模式之原型模式(Prototype模式)介绍
- 干货:Java多线程详解(内附源码)编程语言
- Java之多线程断点下载的实现详解编程语言
- Java基础之关键字static详解编程语言
- Java经典实例:在文本中匹配换行符详解编程语言
- Oracle 视图 USER_JAVA_INNERS 官方解释,作用,如何使用详细说明
- Java连接MySQL数据库的简单步骤(java如何连接mysql数据库)
- Java多线程超详解编程语言
- Java程序构建基于Redis的缓存系统(java用redis)
- 面试前准备:Java技术和Redis快速入门(java面试redis)
- Linux环境中如何顺利执行Java程序?(linux下执行java)
- Java与Linux:前景迷人的新科技(java和linux前景)
- Linux与Java结合:开启全新的编程之旅(linux java())