spark源码分析之ReadAheadInputStream

概述

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 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值