안녕하세요! NIO 공급업체로서 저는 Java NIO 비동기 I/O의 세계를 깊이 탐구해 왔으며 오늘은 Java NIO 비동기 I/O에서 CompletionHandler를 사용하는 방법을 여러분과 공유하게 되어 기쁘게 생각합니다. 특히 고성능 I/O 작업을 처리할 때 프로그래밍 게임의 수준을 실제로 높일 수 있는 매우 멋진 개념입니다.
먼저, Java NIO 비동기 I/O가 무엇인지 이해해 봅시다. 기존 Java I/O에서는 작업이 차단됩니다. 즉, 파일에서 읽거나 네트워크 소켓에서 데이터를 가져오는 것과 같은 I/O 작업을 수행할 때 프로그램은 해당 작업이 완료될 때까지 기다려야 다음 작업으로 넘어갈 수 있습니다. 이는 특히 프로그램이 대기 상태에 머무르는 것을 원하지 않는 트래픽이 많은 응용 프로그램에서 실제로 방해가 될 수 있습니다.
반면에 Java NIO 비동기 I/O를 사용하면 I/O 작업이 진행되는 동안 프로그램이 다른 작업을 계속 수행할 수 있습니다. 콜백 기반 또는 미래 기반 접근 방식을 사용하여 작업이 완료되면 프로그램에 알립니다. 이것이 바로 CompletionHandler가 들어오는 곳입니다.
CompletionHandler는 두 가지 메소드를 정의하는 Java NIO의 인터페이스입니다.완전한그리고실패한. 그만큼완전한메서드는 비동기 I/O 작업이 성공적으로 완료되면 호출되며 작업 결과에 대한 액세스를 제공합니다. 그만큼실패한작업 중에 문제가 발생하면 메서드가 호출되며 오류에 대한 정보를 제공합니다.
비동기 파일 읽기에 CompletionHandler를 사용하는 간단한 예부터 시작해 보겠습니다.
import java.nio.ByteBuffer; java.nio.channels.AsynchronousFileChannel 가져오기; import java.nio.channels.CompletionHandler; import java.nio.file.Path; import java.nio.file.Paths; import java.nio.file.StandardOpenOption; 공용 클래스 AsyncFileReadExample { 공용 정적 void main(String[] args) { 경로 경로 = Paths.get("test.txt"); 시도 (AsynchronousFileChannel fileChannel = AsynchronousFileChannel.open(path, StandardOpenOption.READ)) { ByteBuffer buffer = ByteBuffer.allocate(1024); fileChannel.read(buffer, 0, buffer, new CompletionHandler<Integer, ByteBuffer>() { @Override public void done(Integer result, ByteBuffer attachment) { System.out.println("Read " + result + " bytes"); buffer.flip(); byte[] data = new byte[buffer.limit()]; buffer.get(data); System.out.println(new String(data)); } @Override public void failed(Throwable ex, ByteBuffer 첨부) { System.err.println("읽기 실패: " + ex.getMessage()); // 읽기 작업이 진행되는 동안 다른 작업을 수행합니다. System.out.println("Doing other task..."); Thread.sleep(2000); } catch (예외 e) { e.printStackTrace(); } } }
이 예에서는 먼저비동기파일채널독서를 위해. 그런 다음 우리는바이트버퍼우리가 읽을 데이터를 보관하기 위해. 우리는읽다버퍼, 읽기 시작 위치(이 경우 0), 첨부 파일(작업과 함께 전달하려는 모든 객체일 수 있음) 및 인스턴스를 파일 채널에 전달합니다.완료 처리기.


그만큼완전한의 방법완료 처리기읽기 작업이 성공하면 호출됩니다. 읽은 바이트 수를 인쇄하고 버퍼를 뒤집은 다음 버퍼 내용을 문자열로 인쇄합니다. 그만큼실패한읽기 작업 중에 오류가 발생하면 메서드가 호출되고 오류 메시지가 인쇄됩니다.
읽기 작업이 진행되는 동안 우리 프로그램은 다른 작업을 계속할 수 있습니다. 이 간단한 예에서는 메시지를 인쇄한 다음 몇 초 동안 휴면합니다.
이제 네트워크 I/O에 CompletionHandler를 사용하는 방법에 대해 이야기해 보겠습니다. 클라이언트-서버 애플리케이션을 구축 중이고 들어오는 연결을 비동기적으로 처리하려고 한다고 가정합니다.
import java.io.IOException; import java.net.InetSocketAddress; import java.nio.ByteBuffer; java.nio.channels.AsynchronousServerSocketChannel 가져오기; java.nio.channels.AsynchronousSocketChannel 가져오기; import java.nio.channels.CompletionHandler; 공용 클래스 AsyncServerExample { 공용 정적 void main(String[] args) { try (AsynchronousServerSocketChannel serverSocketChannel = AsynchronousServerSocketChannel.open()) { serverSocketChannel.bind(new InetSocketAddress(8080)); System.out.println("서버가 포트 8080에서 시작되었습니다."); serverSocketChannel.accept(null, new CompletionHandler<AsynchronousSocketChannel, Void>() { @Override public void done(AsynchronousSocketChannel clientChannel, Void attachment) { serverSocketChannel.accept(null, this); System.out.println("새 클라이언트 연결됨"); ByteBuffer buffer = ByteBuffer.allocate(1024); clientChannel.read(buffer, buffer, new CompletionHandler<Integer, ByteBuffer>() { @Override public void done(Integer result, ByteBuffer attachment) { if (result > 0) { attachment.flip(); byte[] data = new byte[attachment.limit()]; attachment.get(data); String message = new String(data); System.out.println("Received: " + message); try { clientChannel.write(ByteBuffer.wrap(("You sent: " + message).getBytes())).get(); } catch (Exception e) { e.printStackTrace(); } } try { clientChannel.close(); } catch (IOException e) { e.printStackTrace() } } @Override public void failed(Throwable ex, ByteBuffer attachment) failed: " + exc.getMessage()); try { clientChannel.close(); } catch (IOException e) { e.printStackTrace(); } } }); } @Override public void failed(Throwable ex, Void attachment) { System.err.println("Accept failed: " + ex.getMessage()); } }); // 서버 실행을 유지합니다. Thread.sleep(Long.MAX_VALUE); } catch (예외 e) { e.printStackTrace(); } } }
이 서버 예에서는비동기서버소켓채널포트 8080에 바인딩합니다. 그런 다음수용하다서버 소켓 채널의 메서드를 전달하여완료 처리기. 새 클라이언트가 연결되면완전한의 방법완료 처리기호출됩니다. 이 메서드 내에서 우리는 또 다른 연결을 수락하고(서버가 여러 클라이언트를 처리할 수 있도록) 새 클라이언트가 연결되었음을 나타내는 메시지를 인쇄한 다음 클라이언트에서 데이터를 읽기 시작합니다.
우리는 다른 것을 사용합니다완료 처리기읽기 작업을 위해. 읽기가 성공하면 수신된 메시지를 인쇄하고 클라이언트에 응답을 다시 보냅니다. 오류가 있으면 오류 메시지를 인쇄하고 클라이언트 채널을 닫습니다.
Java NIO 비동기 I/O에서 CompletionHandler를 사용할 때의 가장 큰 장점 중 하나는 프로그램을 차단하지 않고 여러 I/O 작업을 동시에 처리할 수 있다는 것입니다. 이를 통해 특히 클라이언트 수가 많거나 대용량 데이터 전송이 있는 시나리오에서 훨씬 더 효율적이고 응답성이 뛰어난 애플리케이션을 구현할 수 있습니다.
전기차에 관심이 많으신 분들은니오 ET5 전기 자동차. CompletionHandler가 Java NIO 비동기 I/O에서 효율성과 유연성을 결합한 것처럼 스타일과 기술을 결합한 세련된 고성능 전기 자동차입니다.
NIO 공급업체로서 저는 고성능과 안정적인 시스템의 중요성을 알고 있습니다. 자동차 산업이든 소프트웨어 프로그래밍이든 우리는 항상 최적화하고 개선할 수 있는 방법을 찾고 있습니다. Java NIO 비동기 I/O에 대해 자세히 알아보고 싶거나 제품 및 서비스와 관련된 요구 사항이 있는 경우 주저하지 말고 문의하세요. 우리는 귀하의 프로젝트를 한 단계 더 발전시킬 수 있도록 도와드립니다. 귀하의 요구 사항을 충족하기 위해 어떻게 협력할 수 있는지 대화를 나누십시오.
참고자료:
- 자바 NIO 문서
- 다양한 온라인 프로그래밍 튜토리얼 및 블로그



























































