Java NIOとリアクターモード
8911 ワード
一、Java NIOプロフィールJava NIO非ブロックアプリケーションは通常I/O読み書きなどに適用される.システムが動作するパフォーマンスのボトルネックは、ポートやファイルの操作を含むI/O読み書きにあることがよく知られています.従来、I/Oチャネルを開くと、read()はポートがバイトコンテンツを読み出すのを一度待っていたため、リソースが非常に消費されました.
Java NIO非ブロック技術は実際にReactorモードを採用している.彼はI/Oポートを監視してくれて、もし内容が入ってきたら、自動的に私たちに知らせてくれます.そうすれば、私たちは複数のスレッドの死などを開く必要はありません.外部から見ると、スムーズなI/O読み書きを実現し、ブロックされません.
二、NIOの基本原理NIOには主なクラスSelectorがあります.これは観察者のようなものです.私たちが探知する必要があるsocketchannelをselectorに伝えさえすれば、私たちは他のことをします.何かあったら、彼は私たちに知らせて、selectionkeyのグループに戻って、私たちはこれらのkeyを読んで、私たちが登録したばかりのsocketchannelを手に入れます.そして、私たちはこのchannelからデータを読み出します.
selectorの内部原理は実際に登録されたchannelへのポーリングアクセスを行い、絶えずポーリングを行い、このchannelにポーリングして登録されたことが発生すると、データが来たら、彼は立ち上がって報告し、鍵を渡して、この鍵を通じてこのchannelの内容を読み取りましょう.
使用上:
これは、ポート9000に待機しているnoblock serverの例です.クライアントプログラムを作成すると、インタラクティブに操作したり、telnetホスト名90000を使用してリンクしたりすることができます.
Java NIO非ブロック技術は実際にReactorモードを採用している.彼はI/Oポートを監視してくれて、もし内容が入ってきたら、自動的に私たちに知らせてくれます.そうすれば、私たちは複数のスレッドの死などを開く必要はありません.外部から見ると、スムーズなI/O読み書きを実現し、ブロックされません.
二、NIOの基本原理NIOには主なクラスSelectorがあります.これは観察者のようなものです.私たちが探知する必要があるsocketchannelをselectorに伝えさえすれば、私たちは他のことをします.何かあったら、彼は私たちに知らせて、selectionkeyのグループに戻って、私たちはこれらのkeyを読んで、私たちが登録したばかりのsocketchannelを手に入れます.そして、私たちはこのchannelからデータを読み出します.
selectorの内部原理は実際に登録されたchannelへのポーリングアクセスを行い、絶えずポーリングを行い、このchannelにポーリングして登録されたことが発生すると、データが来たら、彼は立ち上がって報告し、鍵を渡して、この鍵を通じてこのchannelの内容を読み取りましょう.
使用上:
package reactor.section3;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.Set;
public class NBTest1 {
private static void printKeyInfo(SelectionKey sk) {
String s = new String();
s += "Att: " + (sk.attachment() == null ? "no" : "yes");
s += ", Read: " + sk.isReadable();
s += ", Acpt: " + sk.isAcceptable();
s += ", Cnct: " + sk.isConnectable();
s += ", Wrt: " + sk.isWritable();
s += ", Valid: " + sk.isValid();
s += ", Ops: " + sk.interestOps();
debug(s);
}
private static void debug(String s) {
System.out.println(s);
}
public static void main(String args[]) {
NBTest1 nbTest = new NBTest1();
try {
nbTest.startServer();
} catch (Exception e) {
e.printStackTrace();
}
}
private void startServer() throws Exception{
int channels = 0;
int nKeys = 0;
int currentSelector = 0;
// Selector
Selector selector = Selector.open();
// Channel 9000
ServerSocketChannel ssc = ServerSocketChannel.open();
InetSocketAddress address = new InetSocketAddress(InetAddress.getLocalHost(),9000);
ssc.socket().bind(address);
// non-blocking 。
ssc.configureBlocking(false);
// Selector Channel
SelectionKey s = ssc.register(selector, SelectionKey.OP_ACCEPT);
printKeyInfo(s);
while(true) //
{
debug("NBTest: Starting select");
//Selector select 。
nKeys = selector.select();
// , 0
if(nKeys > 0){
debug("NBTest: Number of keys after select operation: " +nKeys);
Set selectedKeys = selector.selectedKeys();
Iterator i = selectedKeys.iterator();
while(i.hasNext()){
s = (SelectionKey) i.next();
printKeyInfo(s);
debug("NBTest: Nr Keys in selector: " +selector.keys().size());
// key , (ready keys)
i.remove();
if(s.isAcceptable()){
// channel() channel。
Socket socket = ((ServerSocketChannel)s.channel()).accept().socket();
SocketChannel sc = socket.getChannel();
sc.configureBlocking(false);
sc.register(selector, SelectionKey.OP_READ |SelectionKey.OP_WRITE);
System.out.println(++channels);
}else{
debug("NBTest: Channel not acceptable");
}
}
}else{
debug("NBTest: Select finished without any keys.");
}
}
}
}
これは、ポート9000に待機しているnoblock serverの例です.クライアントプログラムを作成すると、インタラクティブに操作したり、telnetホスト名90000を使用してリンクしたりすることができます.