下面举一些异步和阻塞的操作实例:
在 Cassandra 中要查询数据通常会往多个数据节点发送查询命令,但是要检查每个节点返回数据的完整性,所以需要一个异步查询同步结果的应用场景,部分代码如下:
清单 3.异步查询同步结果
class AsyncResult implements IAsyncResult{ private byte[] result_; private AtomicBoolean done_ = new AtomicBoolean(false); private Lock lock_ = new ReentrantLock(); private Condition condition_; private long startTime_; public AsyncResult(){ condition_ = lock_.newCondition();// 创建一个锁 startTime_ = System.currentTimeMillis(); } /*** 检查需要的数据是否已经返回,如果没有返回阻塞 */ public byte[] get(){ lock_.lock(); try{ if (!done_.get()){condition_.await();} }catch (InterruptedException ex){ throw new AssertionError(ex); }finally{lock_.unlock();} return result_; } /*** 检查需要的数据是否已经返回 */ public boolean isDone(){return done_.get();} /*** 检查在指定的时间内需要的数据是否已经返回,如果没有返回抛出超时异常 */ public byte[] get(long timeout, TimeUnit tu) throws TimeoutException{ lock_.lock(); try{ boolean bVal = true; try{ if ( !done_.get() ){ long overall_timeout = timeout - (System.currentTimeMillis() - startTime_); if(overall_timeout > 0)// 设置等待超时的时间 bVal = condition_.await(overall_timeout, TimeUnit.MILLISECONDS); else bVal = false; } }catch (InterruptedException ex){ throw new AssertionError(ex); } if ( !bVal && !done_.get() ){// 抛出超时异常 throw new TimeoutException("Operation timed out."); } }finally{lock_.unlock(); } return result_; } /*** 该函数拱另外一个线程设置要返回的数据,并唤醒在阻塞的线程 */ public void result(Message response){ try{ lock_.lock(); if ( !done_.get() ){ result_ = response.getMessageBody();// 设置返回的数据 done_.set(true); condition_.signal();// 唤醒阻塞的线程 } }finally{lock_.unlock();} } } |
总结
本文阐述的内容较多,从 Java 基本 I/O 类库结构开始说起,主要介绍了磁盘 I/O 和网络 I/O 的基本工作方式,最后介绍了关于 I/O 调优的一些方法。