文章目录
RabbitMQ-java-client版本
com.rabbitmq:amqp-client:4.3.0
RabbitMQ
版本声明: 3.6.15
BlockingCell
-
BlockingCell,代码文档注释描述为”简单的一次性IPC机制“,其实就是一个
Future
对象,大多数长连接里异步处理获取响应值都会采用Future
模式。 -
uml关联
BlockingCell源码分析
-
完整代码,我们从代码结构来看其实就是一个Future
/** * Simple one-shot IPC mechanism. Essentially a one-place buffer that cannot be emptied once filled. * 简单的一次性IPC机制。 基本上是一个缓冲区,一旦填满就不能清空。 * 从代码上来看其实就是一个Future对象 */ public class BlockingCell<T> { /** Indicator of not-yet-filledness * 尚未填充满的标示 * */ private boolean _filled = false; /** Will be null until a value is supplied, and possibly still then. */ private T _value; private static final long NANOS_IN_MILLI = 1000 * 1000; private static final long INFINITY = -1; /** Instantiate a new BlockingCell waiting for a value of the specified type. */ public BlockingCell() { // no special handling required in default constructor } /** * Wait for a value, and when one arrives, return it (without clearing it). If there's already a value present, there's no need to wait - the existing value * is returned. * 一直等待,直到拿到响应数据之后调用set(T newValue),设置值之后调用notifyAll(),此时get()不再阻塞。 * @return the waited-for value * * @throws InterruptedException if this thread is interrupted */ public synchronized T get() throws InterruptedException { while (!_filled) { wait(); } return _value; } /** * Wait for a value, and when one arrives, return it (without clearing it). If there's * already a value present, there's no need to wait - the existing value is returned. * If timeout is reached and value hasn't arrived, TimeoutException is thrown. * * @param timeout timeout in milliseconds. -1 effectively means infinity * @return the waited-for value * @throws InterruptedException if this thread is interrupted */ public synchronized T get(long timeout) throws InterruptedException, TimeoutException { //如果设置为-1,则表示一直等待下去 if (timeout == INFINITY) return get(); if (timeout < 0) { throw new AssertionError("Timeout cannot be less than zero"); } long now = System.nanoTime() / NANOS_IN_MILLI; long maxTime = now + timeout; while (!_filled && (now = (System.nanoTime() / NANOS_IN_MILLI)) < maxTime) { wait(maxTime - now); } if (!_filled) throw new TimeoutException(); return _value; } /** * As get(), but catches and ignores InterruptedException, retrying until a value appears. * @return the waited-for value */ public synchronized T uninterruptibleGet() { boolean wasInterrupted = false; try { while (true) { try { return get(); } catch (InterruptedException ex) { // no special handling necessary wasInterrupted = true; } } } finally { if (wasInterrupted) { Thread.currentThread().interrupt(); } } } /** * As get(long timeout), but catches and ignores InterruptedException, retrying until * a value