728x90
AsynchronousChannel을 지원한다고 한다.
callback 함수를 지정할 수 있고, future로 반환을 지원한다고 한다.
callback과 future를 사용하면 비동기적인 로직이 가능할 것 같다.
- File - callback
우선 callback 함수를 이용해서 파일을 읽어보자.
@Slf4j
public class AsyncFileChannelReadCallbackExample {
@SneakyThrows
public static void main(String[] args) {
log.info("start");
var file = new File("path");
var channel = AsynchronousFileChannel.open(file.toPath());
ByteBuffer byteBuffer = ByteBuffer.allocateDirect(1024);
channel.read(byteBuffer, 0, null, new CompletionHandler<Integer, Object>() {
@SneakyThrows
@Override
public void completed(Integer result, Object attachment) {
byteBuffer.flip();
var resultString = StandardCharsets.UTF_8.decode(byteBuffer);
log.info("result: {}", resultString);
channel.close();
}
@Override
public void failed(Throwable exc, Object attachment) {
}
});
while(channel.isOpen()){
log.info("Reading...");
}
log.info("end");
}
}
completed 함수로 callback을 지정해주어, 파일이 모두 읽히면 result: {}로 내용을 출력할 수 있도록 하였다.
파일이 열린동안 메인 쓰레드가 닫히지 않도록 channel.isOpen으로 대기를 걸어주었다.
이렇게 callback으로 파일의 내용이 출력된 것을 볼 수 있다.
- File - future
@Slf4j
public class AsyncFileChannelReadFutureExample {
@SneakyThrows
public static void main(String[] args) {
log.info("start");
var file = new File("path");
try(var channel = AsynchronousFileChannel.open(file.toPath())){
var buffer = ByteBuffer.allocateDirect(1024);
Future<Integer> channelRead = channel.read(buffer, 0);
while(!channelRead.isDone()){
log.info("Reading...");
}
buffer.flip();
var result = StandardCharsets.UTF_8.decode(buffer);
log.info("result: {}", result);
}
log.info("end");
}
}
이제 Future로 받고, 해당 Future가 끝나기를 기다린 후 파일의 내용을 출력하게 되었다.
코드는 깔끔해졌지만, while에서 동기적으로 동작하게 된다.
- socket - callback
이번엔 소켓이다.
accept하는 부분을 비동기적으로 변경하였다.
@Slf4j
public class AsyncServerSocketCallbackExample {
@SneakyThrows
public static void main(String[] args) {
log.info("start");
var serverSocketChannel = AsynchronousServerSocketChannel.open();
var address = new InetSocketAddress("localhost", 8080);
serverSocketChannel.bind(address);
serverSocketChannel.accept(null, new CompletionHandler<>() {
@Override
public void completed(AsynchronousSocketChannel clientSocket, Object attachment) {
log.info("accepted");
var requestBuffer = ByteBuffer.allocateDirect(1024);
clientSocket.read(requestBuffer, null, new CompletionHandler<>() {
@SneakyThrows
@Override
public void completed(Integer result, Object attachment) {
requestBuffer.flip();
var request = StandardCharsets.UTF_8.decode(requestBuffer);
log.info("request: {}", request);
var response = "I am server";
var responseBuffer = ByteBuffer.wrap(response.getBytes());
clientSocket.write(responseBuffer);
clientSocket.close();
log.info("end");
}
@Override
public void failed(Throwable exc, Object attachment) {
}
});
}
@Override
public void failed(Throwable exc, Object attachment) {
}
});
Thread.sleep(1000000);
log.info("end");
}
}
Callback이 2개이다.
바깥은 accept하는 부분이고, 안 쪽은 read하는 부분의 callback이다.
- socket - Future
@Slf4j
public class AsyncServerSocketFutureExample {
@SneakyThrows
public static void main(String[] args) {
log.info("start");
var serverSocketChannel = AsynchronousServerSocketChannel.open();
var address = new InetSocketAddress("localhost", 8080);
serverSocketChannel.bind(address);
Future<AsynchronousSocketChannel> clientSocketFuture = serverSocketChannel.accept();
while(!clientSocketFuture.isDone()){
Thread.sleep(100);
log.info("Wainting");
}
var clientSocket = clientSocketFuture.get();
var requestBuffer = ByteBuffer.allocateDirect(1024);
Future<Integer> channelRead = clientSocket.read(requestBuffer);
while(!channelRead.isDone()){
log.info("Reading...");
}
requestBuffer.flip();
var request = StandardCharsets.UTF_8.decode(requestBuffer);
log.info("request: {}", request);
var response = "This is server.";
var responseBuffer = ByteBuffer.wrap(response.getBytes());
clientSocket.write(responseBuffer);
clientSocket.close();
log.info("end client");
}
}
Future로 변경을 해보았다.
File 때와 마찬가지로 while에서 동기적으로 작동하게 되며, 보완이 필요하다고 생각된다.
'백엔드 > 리액티브 프로그래밍' 카테고리의 다른 글
Java Selector (1) | 2024.03.20 |
---|---|
Java IO Server 서버를 NIO로 변경 (0) | 2024.03.19 |
Java NIO (0) | 2024.03.18 |
JAVA IO (0) | 2024.03.18 |
Mutiny (0) | 2024.03.14 |