概述
ReadAheadInputStream实现了从当前buffer读取的data耗尽时,切换到另外一个buffer读取数据,并启动任务从底层输入流异步预读data,放入耗尽的buffer中。它通过2个buffer来完成——active buffer和read ahead buffer。在调用read()方法时会返回active buffer中的数据。而read ahead buffer用于从底层输入流异步读取数据。通过切换这2个buffer,我们可以在active buffer耗尽时开始从read ahead buffer读取数据,无需阻塞在磁盘IO上。
从底层输入流异步读取数据到read ahead buffer ,相当于写线程。
当前线程从read ahead buffer读取数据,相当于读线程(reader)。
在swap buffer、触发async reading、获取async state时需要加锁。
async read在填满read ahead buffer才返回可能会增加延迟,所以如果有reader等待数据,还可以添加一个“AtomicBoolean”标志,以便能够更早地返回。
成员变量
从概述可以得出,我们至少需要以下成员变量:activeBuffer、readAheadBuffer、underlyingInputStream等,同时还需要用于并发的相关成员变量。
private ReentrantLock stateChangeLock = new ReentrantLock();
@GuardedBy("stateChangeLock")
private ByteBuffer activeBuffer;
@GuardedBy("stateChangeLock")
private ByteBuffer readAheadBuffer;
private final InputStream underlyingInputStream;
// whether there is a reader waiting for data.
private AtomicBoolean isWaiting = new AtomicBoolean(false);
private final ExecutorService executorService =
ThreadUtils.newDaemonSingleThreadExecutor("read-ahead");
@GuardedBy("stateChangeLock")
// true if async read is in progress
//判断async read是否完成的条件变量,如果为true,表示仍在进行
private boolean readInProgress;
//阻塞等待async read完成的condition实例
private final Condition asyncReadComplete = stateChangeLock.newCondition();
read方法
@Override
public int read(byte[] b, int offset, int len) throws IOException {
if (offset < 0