4 台のマシンに接続し、ソケットからデータを読み取る必要があります。nio2 の非同期モデルを使用することにしました。
ここに疑似コードがあります:
class Connector {
private final AsynchronousChannelGroup group;
private final String host;
private final int port
//...
public void connect() {
try (AsynchronousSocketChannel client = AsynchronousSocketChannel.open(group)) {
client.connect(new InetSocketAddress(host(), port())).get(5, TimeUnit.SECONDS);
if (!group.isShutdown()) {
ByteBuffer buffer = ByteBuffer.allocate(1024);
client.read(buffer, 5, TimeUnit.SECONDS, new Attachement(buffer), new ReadHandler(client)); //#1
}
} catch (Exception e) {
//
}
}
private class ReadHandler implements CompletionHandler<Integer, Attachement> {
final AsynchronousSocketChannel channel;
@Override
public void completed(Integer result, Attachement attachment) {
attachment.buffer.clear();
channel.read(attachment.buffer, 5, TimeUnit.SECONDS, attachment, this);
}
@Override
public void failed(Throwable exc, Attachement attachment) {
closeChannel();
}
void closeChannel() {
try {
if (channel.isOpen()) {
channel.close();
}
} catch (IOException e) {
// do something else
}
}
}
}
このコードを実行するには、新しいグループを作成し、それをすべてのConnector
sに渡します。
ExecutorService executor = Executors.newFixedThreadPool(4);
AsynchronousChannelGroup group = AsynchronousChannelGroup.withThreadPool(executor);
//for each server
Connector connectorX = new Connector(group, serverX.host, serverX.port);
問題:
スレッドは、最初の読み取り (//#1
コメントがある場所) の後に解放されます。
解決 !
これを修正するCountDownLatch
ために、スレッドが読み取りを待機するように を導入しました。
//...
private CountDownLatch latch;
public void connect() {
latch = new CountDownLatch(1);
try (AsynchronousSocketChannel client = AsynchronousSocketChannel.open(group)) {
client.connect(new InetSocketAddress(host(), port())).get(5, TimeUnit.SECONDS);
if (!group.isShutdown()) {
ByteBuffer buffer = ByteBuffer.allocate(1024);
client.read(buffer, 5, TimeUnit.SECONDS, new Attachement(buffer), new ReadHandler(client)); //#1
}
latch.await();
} catch (Exception e) {
//...
latch.countDown();
}
}
質問:
これは ( CountDownLatch
) 問題を解決する正しい方法ですか? いいえの場合、最善の方法は何ですか?
スレッドのブロック ( latch.await()
) は、非同期モデルと矛盾していませんか?