Netty权威指南之伪异步I/O编程
生活随笔
收集整理的這篇文章主要介紹了
Netty权威指南之伪异步I/O编程
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
為了解決同步阻塞I/O一個鏈路需要一個線程處理問題,對BIO模型做了優化——后端通過一個線程池處理多個客戶端的請求接入,設置線程最大值,防止線程并發接入導致的線程耗盡。
當有新的客戶端接入時,將客戶端Socket封裝成一個Task(該任務實現java.lang.Runnable接口)投遞到后端的線程池中進行處理,JDK的線程池維護一個消息隊列和N個活躍線程,對消息隊列中的任務進行處理。由于線程池可以設置消息隊列的大小和最大線程數,因此資源占用是可控的,無論多少客戶端并發訪問都不會導致資源耗盡和宕機。
偽異步I/O通信框架采用了線程池實現,避免了每次請求創建一個獨立的線程造成的資源耗盡問題,底層通信依然采用BIO同步阻塞模型,無法從根本上解決問題。當對方發送請求或者應答消息比較緩慢(如數據大),或者網路傳輸較慢時(網速差)讀取輸入流一方的通信線程將被長時間阻塞,阻塞期間,其他接入消息只能在消息隊列中排隊。阻塞結束情況:1)有數據可讀,2)可用數據已經讀取完畢,3)發生空指針或IO異常
package com.hjp.netty.pseudoasynio;import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.ExecutorService; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit;public class TimeServerHandlerExecutePool {private ExecutorService executor;public TimeServerHandlerExecutePool(int maxPoolSize, int queueSize) {executor = new ThreadPoolExecutor(Runtime.getRuntime().availableProcessors(), maxPoolSize, 120L, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(queueSize));}public void execute(Runnable task) {executor.execute(task);}} 線程池處理類 package com.hjp.netty.pseudoasynio;import sun.awt.windows.ThemeReader;import java.io.IOException; import java.net.ServerSocket; import java.net.Socket;public class TimeServer {public static void main(String[] args) throws IOException {int port = 8080;if (args != null && args.length > 0) {try {port = Integer.valueOf(port);} catch (NumberFormatException e) {e.printStackTrace();}}ServerSocket server = null;try {server = new ServerSocket(port);System.out.println("The time server is start in port : " + port);Socket socket = null;TimeServerHandlerExecutePool singleExecutor = new TimeServerHandlerExecutePool(50, 10000);while (true) {socket = server.accept();singleExecutor.execute(new TimeServerHandler(socket));}} finally {if (server != null) {System.out.println("The time server close");server.close();server = null;}}}} TimeServer package com.hjp.netty.pseudoasynio;import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.Socket; import java.util.Date;public class TimeServerHandler implements Runnable {private Socket socket;public TimeServerHandler(Socket socket) {this.socket = socket;}@Overridepublic void run() {BufferedReader in = null;PrintWriter out = null;try {in = new BufferedReader(new InputStreamReader(this.socket.getInputStream()));out = new PrintWriter(this.socket.getOutputStream(), true);String currentTime = null;String body = null;while (true) {body = in.readLine();if (body == null) {break;}System.out.println("The time server receive order : " + body);currentTime = "QUERY TIME ORDER".equalsIgnoreCase(body) ? new Date(System.currentTimeMillis()).toString() : "BAD ORDER";out.println(currentTime);}} catch (Exception e) {if (in != null) {try {in.close();} catch (IOException e1) {e1.printStackTrace();}}if (out != null) {out.close();out = null;}if (this.socket != null) {try {this.socket.close();} catch (IOException e1) {e1.printStackTrace();}this.socket = null;}}} } TimeServerHandler客戶端代碼和BIO客戶端代碼一樣
總結
以上是生活随笔為你收集整理的Netty权威指南之伪异步I/O编程的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: IE与Chrome对相对URL解析的区别
- 下一篇: Shell字符串处理之 ${}