NIOチャネルインターフェイスの分析



NIOチャンネルソースコード解析

ディレクトリ

NIO-概要
NIOバッファ
NIOチャンネル
NIOチャンネルソースコード解析

序文

ネッティーは学びたいと思ったが、ネッティーはそうネッティー学習、または何NIOの知識を整理する前に、NIOフレームワークです。解析することで、ソースコードを NIOの設計原理を理解します。

JDK1.8.0.161ソースを目的とした記事のこのシリーズ。

前は、分析のためのチャネルインターフェイス上で、以下、チャンネルの基本的な使用を記載しています。

インターフェース

SCTPプロトコル

SCTP(ストリーム制御伝送プロトコル)伝送プロトコルであるTCP / IPプロトコルスタックとの両方TCP / UDPのTCP、UDP同様に、両特性の位置。

SCTPプロトコルは、ここでは詳細に説明されていないために、私は、学生が見ることができます知ってほしいこの記事
は通常あまり使用されないSCTPプロトコル、特にここでは説明しません。

UDPプロトコル

NIOの使用は、ネットワーク通信プロトコルUDPを達成DatagrmChannel。

20191207210432.png

ここでは、さまざまなインタフェースを分析します。

AutoCloseableそしてCloseable自動的に近いオフとインターフェイスアクティブです。(などのハンドルやファイル、など)場合は、リソース解放する必要がある、あなたはリソースを解放するためにcloseメソッドを呼び出す必要があります。

public interface AutoCloseable {
    void close() throws Exception;
}

public interface Closeable extends AutoCloseable {
    void close() throws IOException;
}

Channel関連するI / Oの動作のためのチャネルインタフェースは、開閉動作を必要とします。

public interface Channel extends Closeable {
    boolean isOpen();

    void close() throws IOException;
}

InterruptibleChannelこれは、チャネルインターフェースの非同期クローズと割り込みをサポートすることです。スレッドが中断されたときにthead要素に割り込みモデルをサポートするために、あなたはリリースチャンネルを閉じるために、割り込み処理のコールバックオブジェクトを実行することができます。

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

約InterruptibleChannel割り込み可能I / O詳細な分析を見ることができます「-InterruptibleChannelと割り込みIOを読んJDKのソースコード」

Interruptible是线程中断接口,即上面提的Thead的interrupt模型。当线程中断时,则会调用中断操作。

public abstract interface Interruptible {
    public abstract void interrupt(java.lang.Thread t);
}
public class Thread implements Runnable {
    ...
    public void interrupt() {
        if (this != Thread.currentThread())
            checkAccess();

        synchronized (blockerLock) {
            Interruptible b = blocker;
            if (b != null) {
                interrupt0();           // Just to set the interrupt flag
                b.interrupt(this);
                return;
            }
        }
        interrupt0();
    }
    ...
}

AbstractInterruptibleChannel实现了ChannelInterruptibleChannel接口。

20191208013708.png

  • closeLock是关闭时的锁
  • open表示channle是否打开
  • interuptorInterruptible中断回调
  • interrupted为I/O执行时的线程
public abstract class AbstractInterruptibleChannel implements Channel, InterruptibleChannel {
    ...
    public final void close() throws IOException {
        synchronized(this.closeLock) {
            if (this.open) {
                this.open = false;
                this.implCloseChannel();
            }
        }
    }
    //具体的Channel实现关闭
    protected abstract void implCloseChannel() throws IOException;

    protected final void begin() {
        if (this.interruptor == null) {
            this.interruptor = new Interruptible() {
                //线程中断时,则会调用该接口关闭Channel
                public void interrupt(Thread target) {
                    synchronized(AbstractInterruptibleChannel.this.closeLock) {
                        if (AbstractInterruptibleChannel.this.open) {
                            AbstractInterruptibleChannel.this.open = false;
                            AbstractInterruptibleChannel.this.interrupted = target;

                            try {
                                AbstractInterruptibleChannel.this.implCloseChannel();
                            } catch (IOException x) {
                            }

                        }
                    }
                }
            };
        }
        //将线程的blockOn设置为当前interruptor,从而使得线程关闭时能关闭channel
        blockedOn(this.interruptor);
        Thread me = Thread.currentThread();
        if (me.isInterrupted()) {
            this.interruptor.interrupt(me);
        }

    }

    protected final void end(boolean completed)
        throws AsynchronousCloseException
    {
        //I/O结束,清除线程blocker
        blockedOn(null);
        Thread interrupted = this.interrupted;
        if (interrupted != null && interrupted == Thread.currentThread()) {
            interrupted = null;
            throw new ClosedByInterruptException();
        }
        if (!completed && !open)
            throw new AsynchronousCloseException();
    }

    static void blockedOn(Interruptible intr) {
        SharedSecrets.getJavaLangAccess().blockedOn(Thread.currentThread(), intr);
    }
}

AbstractInterruptibleChannel添加了beginend方法。 在I/O操作开始时会调用begin,在I/O操作结束时会调用end。在begin方法内将中断操作加入到当前线程中。最终会调用到线程的blockOn方法,它会将该中断接口注入到线程中,使得线程中断时可以调用到Channel并释放相关资源。

public void blockedOn(Thread t, Interruptible b) {
    t.blockedOn(b);
}

SelectableChannel接口声明了Channel是可以被选择的,在Windows平台通过WindowsSelectorImpl实现,Linux通过EPollSelectorImpl实现。此外还有KQueue等实现,关于Selector具体细节在《NIO-Selector》一文中会介绍。

AbstractSelectableChannel实现了SelectableChannel接口。

NetworkChannel适用于网络传输的接口。

public interface NetworkChannel extends Channel {
    //绑定地址
    NetworkChannel bind(SocketAddress var1) throws IOException;

    //获取本地地址
    SocketAddress getLocalAddress() throws IOException;

    //设置socket选项
    <T> NetworkChannel setOption(SocketOption<T> var1, T var2) throws IOException;
    //获取socket选项
    <T> T getOption(SocketOption<T> var1) throws IOException;
    //当前通道支持的socket选项
    Set<SocketOption<?>> supportedOptions();
}

MulticastChannel是支持组播接口。

public interface MulticastChannel extends NetworkChannel {
    void close() throws IOException;

    MembershipKey join(InetAddress group, NetworkInterface interf) throws IOException;

    MembershipKey join(InetAddress group, NetworkInterface interf, InetAddress source) throws IOException;
}

SelChImpl接口用于将底层的I/O就绪状态更新为就绪事件。

public interface SelChImpl extends Channel {

    FileDescriptor getFD();
    int getFDVal();
    //更新就绪事件
    public boolean translateAndUpdateReadyOps(int ops, SelectionKeyImpl sk);
    //设置就绪事件
    public boolean translateAndSetReadyOps(int ops, SelectionKeyImpl sk);
    //将底层的轮询操作转换为事件
    void translateAndSetInterestOps(int ops, SelectionKeyImpl sk);
    //返回channle支持的操作,比如读操作、写操作等
    int validOps();
    void kill() throws IOException;
}

由于UDP支持读写数据,因此还实现了ReadableByteChannelWritableByteChannel接口

public interface ReadableByteChannel extends Channel {
    int read(ByteBuffer dst) throws IOException;
}   

public interface WritableByteChannel extends Channel {
    int write(ByteBuffer src) throws IOException;
}

ByteChannel是支持读写的通道。

public interface ByteChannel extends ReadableByteChannel, WritableByteChannel {
}

ScatteringByteChannel则支持根据传入偏移量读,支持根据传入偏移量写GatheringByteChannel

public interface ScatteringByteChannel extends ReadableByteChannel {
    long read(ByteBuffer[] dsts, int offset, int length) throws IOException;
    long read(ByteBuffer[] dsts) throws IOException;}

public interface GatheringByteChannel extends WritableByteChannel {
    long write(ByteBuffer[] srcs, int offset, int length) throws IOException;
    long write(ByteBuffer[] srcs) throws IOException;
}

TCP协议

客户端

20191209111550.png

TCP协议除了不支持组播,其他和UDP是一样的,不再重复介绍。

服务端

20191209112800.png

服务端无需数据读写,仅需要接收连接,数据读写是SocketChannel干的事。因此没有ReadableByteChannelWriteableByteChannel等读写接口

文件

20191209112005.png

少ないネットワークプロトコルよりもファイルNetworkChannelSelChImplおよびSelectableChannelSelChImplそしてSelectableChannel主にアイドル伝送ネットワーク接続の大半ので、セレクタをサポートするために使用され、したがって、支持大幅に性能を向上させることができる多重接続中にデータが到着する場合、必要に高い同時実行をサポートするために知りません、ディスクの読み取りと書き込みがありませんセレクタので、需要はないながら。

SeekableByteChannelあなたは位置のサポートを修正することにより、指定された場所からデータを読み書きすることができます。

public interface SeekableByteChannel extends ByteChannel {
    int read(ByteBuffer dst) throws IOException;

    int write(ByteBuffer src) throws IOException;
    
    long position() throws IOException;
    //设置偏移量
    SeekableByteChannel position(long newPosition) throws IOException;

    long size() throws IOException;
    //截取指定大小
    SeekableByteChannel truncate(long size) throws IOException;
}

概要

記事の長さがあるので、それを分析し、別々に分析を実装するためのインタフェースます。チャネルインターフェイス上でこの記事が記載され、次は具体的な実装を分析することになります。

関連文書

  1. SCTPプロトコルは、詳細な
  2. 最悪のJava NIOエントリ:あきらめ心配するエントリから、これを読んでください!
  3. チュートリアルのJavaのNIOシリーズ
  4. 使用SCTP /ノウハウの理由ではない多くの
  5. JDKのソースコードの読み取り-InterruptibleChannelと割り込みIO
  6. ブロードキャストおよびマルチキャスト
  7. AccessController.doPrivilegedの概要
  8. ServiceLoaderソースコード解析
  9. Javaベースの高性能なRDMA通信ライブラリ(6):SDP - Javaのソケット・ダイレクト・プロトコル

20191127212134.png
マイクロチャネルはJiege注意サブスクリプション番号共有の二次元コード技術スイープ
出典:https://www.cnblogs.com/Jack-Blog/p/12040082.html
著者:Jiege忙しい
としては、「4.0 BY CC」、クリエイティブ・コモンズ、本明細書中で使用されます合意。転載へようこそ、目立つ場所に、ソースとのリンクを明記してください。

おすすめ

転載: www.cnblogs.com/Jack-Blog/p/12040082.html