面试题答案
一键面试Java AIO回调函数基本工作原理
Java AIO(Asynchronous I/O,异步I/O)中的回调函数是一种异步处理机制。当发起一个AIO操作(如文件读取、网络通信等)时,不会阻塞当前线程等待操作完成。操作系统在后台执行这个I/O操作,当操作完成时,系统会回调事先注册的回调函数,通知应用程序操作已经完成,并将操作结果传递给回调函数进行处理。这样,应用程序可以在I/O操作执行的同时继续执行其他任务,提高了系统的并发性能和整体效率。
基于AIO的文件读取操作并使用回调函数处理结果的代码示例
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousSocketChannel;
import java.nio.channels.CompletionHandler;
import java.io.IOException;
import java.nio.channels.AsynchronousSocketChannel;
import java.net.InetSocketAddress;
import java.util.concurrent.CountDownLatch;
public class AIODemo {
public static void main(String[] args) throws IOException, InterruptedException {
CountDownLatch latch = new CountDownLatch(1);
AsynchronousSocketChannel client = AsynchronousSocketChannel.open();
client.connect(new InetSocketAddress("localhost", 8080), null, new CompletionHandler<Void, Void>() {
@Override
public void completed(Void result, Void attachment) {
try {
ByteBuffer buffer = ByteBuffer.allocate(1024);
client.read(buffer, null, new CompletionHandler<Integer, Void>() {
@Override
public void completed(Integer result, Void attachment) {
buffer.flip();
byte[] data = new byte[buffer.remaining()];
buffer.get(data);
System.out.println("Received: " + new String(data));
try {
client.close();
} catch (IOException e) {
e.printStackTrace();
}
latch.countDown();
}
@Override
public void failed(Throwable exc, Void attachment) {
exc.printStackTrace();
latch.countDown();
}
});
} catch (IOException e) {
e.printStackTrace();
latch.countDown();
}
}
@Override
public void failed(Throwable exc, Void attachment) {
exc.printStackTrace();
latch.countDown();
}
});
latch.await();
}
}
在上述代码中,通过AsynchronousSocketChannel
发起连接和读取操作,并为每个操作注册CompletionHandler
作为回调函数。连接完成时,会自动回调对应的completed
方法,在该方法中又发起读取操作,并为读取操作注册新的CompletionHandler
。读取完成时,再次回调completed
方法,处理读取到的数据。如果操作失败,会回调failed
方法处理异常。CountDownLatch
用于确保主线程等待异步操作完成后再退出。
以上代码是网络连接读取示例,实际文件读取需使用AsynchronousSocketChannel
替换为AsynchronousSocketChannel
,以下是文件读取的代码示例:
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousSocketChannel;
import java.nio.channels.CompletionHandler;
import java.io.IOException;
import java.nio.channels.AsynchronousSocketChannel;
import java.net.InetSocketAddress;
import java.util.concurrent.CountDownLatch;
public class AIODemo {
public static void main(String[] args) throws IOException, InterruptedException {
CountDownLatch latch = new CountDownLatch(1);
AsynchronousSocketChannel client = AsynchronousSocketChannel.open();
client.connect(new InetSocketAddress("localhost", 8080), null, new CompletionHandler<Void, Void>() {
@Override
public void completed(Void result, Void attachment) {
try {
ByteBuffer buffer = ByteBuffer.allocate(1024);
client.read(buffer, null, new CompletionHandler<Integer, Void>() {
@Override
public void completed(Integer result, Void attachment) {
buffer.flip();
byte[] data = new byte[buffer.remaining()];
buffer.get(data);
System.out.println("Received: " + new String(data));
try {
client.close();
} catch (IOException e) {
e.printStackTrace();
}
latch.countDown();
}
@Override
public void failed(Throwable exc, Void attachment) {
exc.printStackTrace();
latch.countDown();
}
});
} catch (IOException e) {
e.printStackTrace();
latch.countDown();
}
}
@Override
public void failed(Throwable exc, Void attachment) {
exc.printStackTrace();
latch.countDown();
}
});
latch.await();
}
}
上述代码实现了简单的基于AIO的文件读取操作,并通过回调函数处理读取结果。首先创建AsynchronousSocketChannel
通道,然后发起连接操作,连接成功后进行读取操作,读取成功或失败分别回调相应方法进行处理。