Java IO 모델 및 Netty 프레임워크 개요
什么是Netty
异步,基于事件驱动的网络应用框架,用以快速开发高性能,高可靠的网络IO程序
主要针对在TCP协议下,面向Clients端的高并发应用
本质是一个NIO框架,适用于服务器通讯等场景
异步:发送请求无需等待响应,程式接着往下走。
事件驱动:一个连接事件或者断开事件,或者读事件或者写事件,发生后的后续处理。
Netty典型应用:
高性能rpc框架用来远程服务(过程)调用,比如Dubbo。
游戏行业,页面数据交互。
大数据领域如Hadoop高性能通讯和序列化组件(AVRO)。
IO模型
简单理解就是用什么通道去进行数据发送和接收。
BIO:一个连接一个线程,连接不做任何事会造成不必要的线程开销。适用于连接数目较小且固定的架构。
NIO:服务端一个线程(也可以多个),维护一个多路复用器。由多路复用器去处理IO线程。适用于连接数目多且较短的架构
AIO:异步非阻塞,还未得到广泛应用。适用于连接数目多且连接较长的架构。
BIO
BIO编程简单流程
服务端创建启动ServerSocket
客户端启动Socket对服务器进行通信,默认服务器会对每一个客户创建一个线程。
客户端发出请求后,先咨询线程是否有响应,如果没有则等待或者拒绝。
如果有响应,则等待请求结束后,再继续执行。(阻塞)
BIO简单实例
public class BIOserver { public static void main(String[] args) throws IOException { // 为了方便直接用了Executors创建线程池 ExecutorService service = Executors.newCachedThreadPool(); //指定服务端端口 ServerSocket serverSocket = new ServerSocket(6666); System.out.println("服务器启动"); while(true){ //阻塞等待连接 Socket socket = serverSocket.accept(); System.out.println("连接到一个客户端"); //每个连接对应一个线程 service.execute(new Runnable() { @Override public void run() { try { handler(socket); }catch (Exception e){ e.printStackTrace(); } } }); } } public static void handler(Socket socket) throws IOException { System.out.println("Thread:"+Thread.currentThread().getId()); byte[] bytes = new byte[1024]; InputStream inputStream = socket.getInputStream(); while (true){ //阻塞等待读取 int n = inputStream.read(bytes); if(n!=-1){ System.out.println(new String(bytes,0,n)); }else { break; } } socket.close(); } }
测试:使用windows的telnet
使用 ctrl+]
可以在服务端控制台看到,已经读取到发送的数据
NIO
三大核心部分:Channel(可类比Socket),Buffer,Selector
大概是这个样子。客户端和Buffer交互,Buffer和Channel是一对一的关系。Selector选择操作Channel(事件驱动,如果Channel有事件发生,Selector才去选择操作。)
Buffer
Buffer基本使用
ByteBuffer使用场景较为广泛。
buffer就是一个内存块,所以说nio是面向块/缓冲,底层是数组。数据读写是通过buffer。可以使用方法flip切换读写。
public class BufferNio { public static void main(String[] args) { //创建buffer容量为5个int IntBuffer buffer = IntBuffer.allocate(5); //放数据 buffer.put(1); buffer.put(2); buffer.put(3); buffer.put(4); buffer.put(5); //读写切换 buffer.flip(); //取数据 //内部维护一个索引,每次get索引都会往后边移动 while(buffer.hasRemaining()){ System.out.println(buffer.get()); } } }
Buffer四个主要属性
// Invariants: mark <= position <= limit <= capacity private int mark = -1; private int position = 0; private int limit; private int capacity;
mark:标记,很少改变
position:下一个要被读元素的位置,为下次读写做准备
limit:缓冲器当前的终点,不能对缓冲区极限意外的区域读写,可变。
capacity:不可变,创建时指定的最大容量。
上边出现了读写切换的方法flip,我们看下源码,可以看出来通过改变属性实现可读可写的。
public final Buffer flip() { limit = position; position = 0; mark = -1; return this; }
可以通过啊更改limit或者position来实现你想要的操作。参数自己决定
buffer.limit(2); buffer.position(1);
Channel
可读可写,上接Selector,下连Buffer。
当客户端连接ServerSocketChannel时,创建客户端自己的SocketChannel。
本地文件写案例
public class ChannelNio { public static void main(String[] args) throws IOException { String str = "少壮不努力,老大徒伤悲"; //创建输出流 FileOutputStream os = new FileOutputStream("D:\\xxxxxxxxxxxxxxxxxxx\\a.txt"); //获取FileChannel FileChannel channel = os.getChannel(); //创建缓冲 ByteBuffer buffer = ByteBuffer.allocate(1024); //把字符串放入缓冲区 buffer.put(str.getBytes()); //反转ByteBuffer buffer.flip(); //将ByteBuffer写入到FileChannel channel.write(buffer); //关闭流 os.close(); } }
图示理解
本地文件读案例
public class ChannelNio { public static void main(String[] args) throws IOException { FileInputStream is = new FileInputStream("D:\\xxxxxxxxxxxxxxxxxxx\\a.txt"); FileChannel channel = is.getChannel(); ByteBuffer buffer = ByteBuffer.allocate(1024); channel.read(buffer); System.out.println(new String(buffer.array())); is.close(); } }
本地文件拷贝案例
方法一
public class ChannelNio { public static void main(String[] args) throws IOException { FileInputStream is = new FileInputStream("D:\\xxxxxxxxxxxxxxxxxxx\\a.txt"); FileChannel channel = is.getChannel(); ByteBuffer buffer = ByteBuffer.allocate(1024); FileOutputStream os = new FileOutputStream("D:\\xxxxxxxxxxxxxxxxxxx\\b.txt"); FileChannel osChannel = os.getChannel(); while (true){ buffer.clear(); int i = channel.read(buffer); if(i==-1){ break; } buffer.flip(); osChannel.write(buffer); } is.close(); os.close(); } }
方法二
public class ChannelNio { public static void main(String[] args) throws IOException { FileInputStream is = new FileInputStream("D:\\xxxxxxxxxxxxxxxxxxx\\HELP.md"); FileChannel channel = is.getChannel(); FileOutputStream os = new FileOutputStream("D:\\xxxxxxxxxxxxxxxxxxx\\HELP222.md"); FileChannel osChannel = os.getChannel(); osChannel.transferFrom(channel,0,channel.size()); is.close(); os.close(); } }
Selector
用一个线程处理多个客户端连接。可以检测多个注册通道的事件,并作出相应处理。不用维护所有线程。
Selector는 등록된 SocketChannel의 SelectionKey 세트를 획득한 후, select를 듣고, 이벤트 발생 시 SelectionKey를 획득하고, 마지막으로 SelectionKey를 통해 채널을 획득하여 해당 작업을 수행하고 비즈니스를 완료할 수 있습니다.
위 내용은 Java IO 모델 및 Netty 프레임워크 개요의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

핫 AI 도구

Undresser.AI Undress
사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover
사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

Video Face Swap
완전히 무료인 AI 얼굴 교환 도구를 사용하여 모든 비디오의 얼굴을 쉽게 바꾸세요!

인기 기사

뜨거운 도구

메모장++7.3.1
사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전
중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기
강력한 PHP 통합 개발 환경

드림위버 CS6
시각적 웹 개발 도구

SublimeText3 Mac 버전
신 수준의 코드 편집 소프트웨어(SublimeText3)

Java 8은 스트림 API를 소개하여 데이터 컬렉션을 처리하는 강력하고 표현적인 방법을 제공합니다. 그러나 스트림을 사용할 때 일반적인 질문은 다음과 같은 것입니다. 기존 루프는 조기 중단 또는 반환을 허용하지만 스트림의 Foreach 메소드는이 방법을 직접 지원하지 않습니다. 이 기사는 이유를 설명하고 스트림 처리 시스템에서 조기 종료를 구현하기위한 대체 방법을 탐색합니다. 추가 읽기 : Java Stream API 개선 스트림 foreach를 이해하십시오 Foreach 메소드는 스트림의 각 요소에서 하나의 작업을 수행하는 터미널 작동입니다. 디자인 의도입니다

PHP는 서버 측에서 널리 사용되는 스크립팅 언어이며 특히 웹 개발에 적합합니다. 1.PHP는 HTML을 포함하고 HTTP 요청 및 응답을 처리 할 수 있으며 다양한 데이터베이스를 지원할 수 있습니다. 2.PHP는 강력한 커뮤니티 지원 및 오픈 소스 리소스를 통해 동적 웹 컨텐츠, 프로세스 양식 데이터, 액세스 데이터베이스 등을 생성하는 데 사용됩니다. 3. PHP는 해석 된 언어이며, 실행 프로세스에는 어휘 분석, 문법 분석, 편집 및 실행이 포함됩니다. 4. PHP는 사용자 등록 시스템과 같은 고급 응용 프로그램을 위해 MySQL과 결합 할 수 있습니다. 5. PHP를 디버깅 할 때 error_reporting () 및 var_dump ()와 같은 함수를 사용할 수 있습니다. 6. 캐싱 메커니즘을 사용하여 PHP 코드를 최적화하고 데이터베이스 쿼리를 최적화하며 내장 기능을 사용하십시오. 7

PHP와 Python은 각각 고유 한 장점이 있으며 선택은 프로젝트 요구 사항을 기반으로해야합니다. 1.PHP는 간단한 구문과 높은 실행 효율로 웹 개발에 적합합니다. 2. Python은 간결한 구문 및 풍부한 라이브러리를 갖춘 데이터 과학 및 기계 학습에 적합합니다.

PHP는 특히 빠른 개발 및 동적 컨텐츠를 처리하는 데 웹 개발에 적합하지만 데이터 과학 및 엔터프라이즈 수준의 애플리케이션에는 적합하지 않습니다. Python과 비교할 때 PHP는 웹 개발에 더 많은 장점이 있지만 데이터 과학 분야에서는 Python만큼 좋지 않습니다. Java와 비교할 때 PHP는 엔터프라이즈 레벨 애플리케이션에서 더 나빠지지만 웹 개발에서는 더 유연합니다. JavaScript와 비교할 때 PHP는 백엔드 개발에서 더 간결하지만 프론트 엔드 개발에서는 JavaScript만큼 좋지 않습니다.

PHP와 Python은 각각 고유 한 장점이 있으며 다양한 시나리오에 적합합니다. 1.PHP는 웹 개발에 적합하며 내장 웹 서버 및 풍부한 기능 라이브러리를 제공합니다. 2. Python은 간결한 구문과 강력한 표준 라이브러리가있는 데이터 과학 및 기계 학습에 적합합니다. 선택할 때 프로젝트 요구 사항에 따라 결정해야합니다.

phphassignificallyimpactedwebdevelopmentandextendsbeyondit

캡슐은 3 차원 기하학적 그림이며, 양쪽 끝에 실린더와 반구로 구성됩니다. 캡슐의 부피는 실린더의 부피와 양쪽 끝에 반구의 부피를 첨가하여 계산할 수 있습니다. 이 튜토리얼은 다른 방법을 사용하여 Java에서 주어진 캡슐의 부피를 계산하는 방법에 대해 논의합니다. 캡슐 볼륨 공식 캡슐 볼륨에 대한 공식은 다음과 같습니다. 캡슐 부피 = 원통형 볼륨 2 반구 볼륨 안에, R : 반구의 반경. H : 실린더의 높이 (반구 제외). 예 1 입력하다 반경 = 5 단위 높이 = 10 단위 산출 볼륨 = 1570.8 입방 단위 설명하다 공식을 사용하여 볼륨 계산 : 부피 = π × r2 × h (4

PHP가 많은 웹 사이트에서 선호되는 기술 스택 인 이유에는 사용 편의성, 강력한 커뮤니티 지원 및 광범위한 사용이 포함됩니다. 1) 배우고 사용하기 쉽고 초보자에게 적합합니다. 2) 거대한 개발자 커뮤니티와 풍부한 자원이 있습니다. 3) WordPress, Drupal 및 기타 플랫폼에서 널리 사용됩니다. 4) 웹 서버와 밀접하게 통합하여 개발 배포를 단순화합니다.
