Java AIO 认识

在基本熟悉了JDK7中异步IO的关键类,以后有助于我们深入学习。在java语言和平台中,存在广泛使用的网络开源库屈指可数。netty 和mina出自韩国人之手,netty和mina主要使用select网络模型,主要使用jdk中的nio类库。netty 和mina在各个行业被广泛使用。 netty 和mina 以及 java nio本身都是对reactor 模式的实现。在操作系统层面都是通过select函数来实现。在windows操作系统中,出现I/o Completion port 后,被广泛使用来提供网络效率。我们RPG游戏服务器本身就是通过I/O Completion Port实现的。

2009年 jdk7出现后,在语言本身对异步IO操作进行了封装,形成了NIO.2 即AIO. AIO框架 仅仅有一个griizly 以及grizzly自身的升级版。grizzly 的开发者是sun公司研发AIO的主要领导者。更有意思的是,grizzly作者目前从事游戏架构设计,同时也是一名创业者。以后的篇章中,我们主要以grizzly为学习案例。虽然grizzly使用范围,文档都不如netty 和mina,但是grizzly 对于AIO的简单封装足够我们学习使用。在Windows平台下面,Java AIO是通过IOCP实现的,这个可以通过OpenJDK源代码证实。


对于JDK7中关于socket 异步IO操作关键类源代码剖析:


public interface AsynchronousChannel  extends Channel
{
    void close() throws IOException;
}

  • A channel that supports asynchronous I/O operations. Asynchronous I/O operations will usually take one of two forms: 
  • A channel that implements this interface is asynchronously closeable: If an I/O operation is outstanding on the channel and the channel's close method is invoked, then the I/O operation fails with the exception AsynchronousCloseException.Asynchronous channels are safe for use by multiple concurrent threads.
  •  Some channel implementations may support concurrent reading and writing, but may not allow more than one read and one write operation to be outstanding at any given time. 
在JDK7开始存在异步IO操作。AsynchronousChannel接口支持异步IO操作。异步IO操作经常使用如下两种形式。

AsynchronousChannel   接口中存在异步close()方法。当一个IO操作是未完成的,当调用close()方法,则IO操作会抛出异常。

一些AsynchronousChannel   的实现支持并发读写,但是不允许在同时多个线程同时读写一个未完成的IO操作。


public interface AsynchronousByteChannel extends AsynchronousChannel
{
    <A> void read(ByteBuffer dst, A attachment,CompletionHandler<Integer,? super A> handler);
    <A> void write(ByteBuffer src, A attachment, CompletionHandler<Integer,? super A> handler);
    Future<Integer> read(ByteBuffer dst);
    Future<Integer> write(ByteBuffer src);
}

  • An asynchronous channel that can read and write bytes
  • that ByteBuffers are not safe for use by multiple concurrent threads. 
    When a read or write operation is initiated then care must be taken to ensure that the buffer is not accessed until the operation completes.
一个支持对字节序进行读写的异步Channel。

ByteBuffers 在多个并发线程下使用是不安全的。一个异步IO读写操作必须确保在IO操作完成后,ByteBuffers 才能被访问。

在AsynchronousByteChannel  接口中支持2种方式来进行对字节的读写操作。




public abstract class AsynchronousServerSocketChannel implements AsynchronousChannel, NetworkChannel
{
    private final AsynchronousChannelProvider provider;


    /**
     * Initializes a new instance of this class.
     */
    protected AsynchronousServerSocketChannel(AsynchronousChannelProvider provider) 
{
        this.provider = provider;
    }
    /**
     * Returns the provider that created this channel.
     */
    public final AsynchronousChannelProvider provider() 
{
        return provider;
    }
    public static AsynchronousServerSocketChannel open(AsynchronousChannelGroup group) throws IOException
    {
        AsynchronousChannelProvider provider = (group == null) ? AsynchronousChannelProvider.provider() : group.provider();
        return provider.openAsynchronousServerSocketChannel(group);
    }
    public static AsynchronousServerSocketChannel open()throws IOException
    {
        return open(null);
    }
    public final AsynchronousServerSocketChannel bind(SocketAddress local) throws IOException
    {
        return bind(local, 0);
    }
    public abstract AsynchronousServerSocketChannel bind(SocketAddress local, int backlog)throws IOException;


    public abstract <T> AsynchronousServerSocketChannel setOption(SocketOption<T> name, T value) throws IOException;


    public abstract <A> void accept(A attachment, CompletionHandler<AsynchronousSocketChannel,? super A> handler);
    public abstract Future<AsynchronousSocketChannel> accept();
}

An asynchronous channel for stream-oriented listening sockets. 
An asynchronous server-socket channel is created by invoking the open method of this class.
A newly-created asynchronous server-socket channel is open but not yet bound.
It can be bound to a local address and configured to listen for connections by invoking the bind method. 
the accept method is used to initiate the accepting of connections to the channel's socket.
Channels of this type are safe for use by multiple concurrent threads though at most one accept operation can be outstanding at any time.
If a thread initiates an accept operation before a previous accept operation has completed then an AcceptPendingException will be thrown. 


AsynchronousServerSocketChannel  是一个支持面向流的服务器端监听socket.
可以通过静态open()方法来创建一个server-socket.一个新创建的server-socket是打开的,但是没有绑定指定端口。
可以通过bind()函数来绑定指定端口。在AsynchronousServerSocketChannel 类中存在2种方式来接受新socket的链接到临。
虽然,在同一时刻只能最多有一个线程来调用accept()方法,但是在多个线程并发使用AsynchronousServerSocketChannel 是安全的。
如果在一个线程调用accept()操作完成前,另外一个线程来执行accept操作,将会抛出AcceptPendingException异常。
在accept()两种形式,在以后会详细介绍。在AsynchronousServerSocketChannel   类中通过指定open()参数来创建实例非常重要。

public abstract class AsynchronousChannelGroup 
{
    private final AsynchronousChannelProvider provider;
    protected AsynchronousChannelGroup(AsynchronousChannelProvider provider) 
{
        this.provider = provider;
    }
    public final AsynchronousChannelProvider provider()
{
        return provider;
    }
    public static AsynchronousChannelGroup withFixedThreadPool(int nThreads,ThreadFactory threadFactory) throws IOException
    {
        return AsynchronousChannelProvider.provider().openAsynchronousChannelGroup(nThreads, threadFactory);
    }


    public static AsynchronousChannelGroup withCachedThreadPool(ExecutorService executor,int initialSize)throws IOException
    {
        return AsynchronousChannelProvider.provider() .openAsynchronousChannelGroup(executor, initialSize);
    }
    public static AsynchronousChannelGroup withThreadPool(ExecutorService executor)throws IOException
    {
        return AsynchronousChannelProvider.provider().openAsynchronousChannelGroup(executor, 0);
    }
    public abstract boolean isShutdown();
    public abstract boolean isTerminated();
    public abstract void shutdown();
    public abstract void shutdownNow() throws IOException;
    public abstract boolean awaitTermination(long timeout, TimeUnit unit) throws InterruptedException;
}



An asynchronous channel group encapsulates the mechanics required to handle the completion of I/O operations initiated by asynchronous channels that are bound to the group. 
A group has an associated thread pool to which tasks are submitted to handle I/O events and dispatch to completion-handlers that consume the result of asynchronous operations performed on channels in the group.
An asynchronous channel group is created by invoking the withFixedThreadPool or withCachedThreadPool methods defined here.
The associated thread pool is owned by the group; termination of the group results in the shutdown of the associated thread pool. 


Threading
The completion handler for an I/O operation initiated on a channel bound to a group is guaranteed to be invoked by one of the pooled threads in the group.
This ensures that the completion handler is run by a thread with the expected identity. 
Where an I/O operation completes immediately, and the initiating thread is one of the pooled threads in the group then the completion handler may be invoked directly by the initiating thread. 
To avoid stack overflow, an implementation may impose a limit as to the number of activations on the thread stack. 
 Some I/O operations may prohibit invoking the completion handler directly by the initiating thread 。


在JDK7中对于异步IO操作主要有2中方式。这两种方式将会重点讲解。其中一个方式存在一个接口。

public interface CompletionHandler<V,A> 
{


    void completed(V result, A attachment);
    void failed(Throwable exc, A attachment);
}




A handler for consuming the result of an asynchronous I/O operation. 
The asynchronous channels defined in this package allow a completion handler to be specified to consume the result of an asynchronous operation.
The completed method is invoked when the I/O operation completes successfully.
The failed method is invoked if the I/O operations fails. 
The implementations of these methods should complete in a timely manner so as to avoid keeping the invoking thread from dispatching to other completion handlers.


为了处理异步IO结果的处理器。当异步IO操作完成时,completed()函数将被调用。


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值