JAVAでreadメソッドによるブロックを解除する方法

Java の read メソッドは通常 InputStream クラスの read メソッドを指します。これは入力ストリームからデータを読み取るメソッドです。読み取れるデータがない場合、read メソッドはデータが到着するまでブロックされます。read メソッドのブロックを解除する必要がある場合は、次の方法を使用できます。

  1. ソケットInputStream、FileInputStreamなどのInputStreamのサブクラスでは、setSoTimeoutメソッドを使用してタイムアウトを設定できます。設定したタイムアウト時間を超えると、readメソッドはSocketTimeoutExceptionまたはIOException例外をスローします。この例外をキャッチすることで、ブロックを解除できます。
InputStream inputStream = socket.getInputStream();
inputStream.setSoTimeout(5000); // 设置超时时间为5秒
try {
    int data = inputStream.read();
    // 读取数据
} catch (SocketTimeoutException e) {
    // 超时处理
} catch (IOException e) {
    // IO异常处理
}
  1. 非ブロッキングIOを使う: NIO(New IO)で提供されるChannelとSelectorを使うと、非ブロッキングな読み取り操作を実現できます。Channelクラスは非ブロッキングなreadメソッドを提供し、Selectorクラスで複数のChannelの読み取り準備イベントを監視できます。
Selector selector = Selector.open();
SocketChannel socketChannel = SocketChannel.open();
socketChannel.configureBlocking(false); // 设置为非阻塞模式
socketChannel.register(selector, SelectionKey.OP_READ); // 注册读就绪事件
selector.select(5000); // 设置超时时间为5秒
Set<SelectionKey> selectedKeys = selector.selectedKeys();
if (selectedKeys.isEmpty()) {
    // 超时处理
} else {
    Iterator<SelectionKey> iterator = selectedKeys.iterator();
    while (iterator.hasNext()) {
        SelectionKey key = iterator.next();
        if (key.isReadable()) {
            SocketChannel channel = (SocketChannel) key.channel();
            ByteBuffer buffer = ByteBuffer.allocate(1024);
            channel.read(buffer);
            // 读取数据
        }
        iterator.remove();
    }
}
  1. スレッドの割り込みを利用する: 入力ストリーム読み込み処理を別個のスレッドに置いて、ブロック解除が必要になった際に、そのスレッドのinterrupt メソッドを呼び出すことでスレッドを割り込み、ブロック解除を行う
Thread readThread = new Thread(() -> {
    try {
        while (!Thread.currentThread().isInterrupted()) {
            int data = inputStream.read();
            // 读取数据
        }
    } catch (IOException e) {
        // IO异常处理
    }
});
readThread.start();

// 取消阻塞
readThread.interrupt();

なお、これらの方法は、例外をスローまたはスレッドを中断することでブロックをキャンセルするため、適切な例外処理コードで後続処理を行う必要があります。

bannerAds