netty(一) java NIO
關于java,其網絡通信方面性能可以說在慢慢挖掘,而且是現今被挖掘出來有效率最高的一塊了,不止2017年,最近這兩年開始,你會發現,java很多組件都采用了NIO的方式,因為其性能確實可以帶來很大提高,從阿里dubbo的廣泛應用netty,到tomcat8以后的NIO通訊,作為一個老程序員,我們發現一定要深入研究java的NIO了,它現在成了java各種應用級開發的核心功能。
在jdk1.4之前,java是沒有NIO的,所有的socket都采用了同步阻塞模式,這以請求一應答的模式簡化了java開發,但在性能和可靠性上卻存在著巨大瓶頸。在jdk1.4中增加了個java.nio包,提供了很多進行異步I/O開發的API和類庫,主要的類和接口如下:
- 進行異步I/O操作的緩沖區ByteBuffer等;
- 進行異步I/O操作的管道Pipe;
- 進行各種I/O操作(異步或者同步)的Channel,包括ServerSocketChannel和SocketChannel;
- 多種字符集的編碼能力和解碼能力;
- 實現非阻塞I/O操作的多路復用器selector;
- 基于流行的Perl實現的正則表達式類庫
- 文件通道FileChannel。
- 沒有統一的文件屬性(例如讀寫權限);
- API能力比較弱,例如目錄的級聯創建和遞歸遍歷,往往需要自己實現;
- 底層存儲系統的一些高級API無法使用;
- 所有的文件操作都是同步阻塞調用,不支持異步文件讀寫操作。
- 提供能夠批量獲取文件屬性的API,這些API具有平臺無關性,不與特性的文件系統相耦合。另外它還提供了標準文件系統的SPI,供各個服務提供商擴展實現;
- 提供AIO功能,支持基于文件的異步i/O操作和針對網絡套接字的異步操作;
傳統的BIO編程是可以
BIO通信模型圖
同步阻塞式I/O創建的TimerServer源碼分析
public class TimerServer {
public static void main(String[] args) throws IOException {
int port = 8080;
if (args != null && args.length > 0) {
try {
port = Integer.valueOf(args[0]);
} catch (NumberFormatException e) {
//采用默認值
}
}
ServerSocket server = null;
try{
server = new ServerSocket(port);
System.out.println("The time server is start in port:" + port);
Socket socket = null;
while (true) {
socket = server.accept();
new Thread(new TimeServerHandler(socket)).start();
}
}finally {
if (server != null) {
System.out.println("The time server close");
server.close();
server = null;
}
}
}
}
TimeServer根據傳入的參數設置監聽端口,如果沒有入參,使用默認值8080.通過構造函數創建ServerSocket,如果端口合法且沒有被占用,服務端監聽成功。之后通過一個無限循環來監聽客戶端的連接,如果沒有客戶端接入,則主線程阻塞在ServerSocket的accept操作上。public class TimeServerHandler implements Runnable {
private Socket socket;
public TimeServerHandler() {
}
public TimeServerHandler(Socket socket) {
this.socket = socket;
}
@Override
public 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) {
}finally{
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;
}
}
}
}
第37行通過BufferedReader讀取一行,如果已經讀到了輸入流的尾部,則返回值為null,推出循環。如果讀到了非空值,則對內容進行判斷,如果請求消息為查詢時間的指令
“QUERY TIME ORDER”,則獲取當前最新的系統時間,通過PrintWriter的println函數發送給客戶端,最后推出循環。
同步阻塞式IO創建的TimeClient源碼分析
客戶端通過Socket創建,發送查詢時間服務器的“QUERY TIME ORDER”命令,然后讀取服務端的響應并將結果打印出來,隨后關閉連接,釋放資源,程序退出執行。public class TimeClient {
public static void main(String[] args) {
int port = 8080;
if (args != null && args.length > 0) {
try {
port = Integer.valueOf(args[0]);
} catch (NumberFormatException e) {
//
}
}
Socket socket = null;
BufferedReader in = null;
PrintWriter out = null;
try {
socket = new Socket("127.0.0.1", port);
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
out = new PrintWriter(socket.getOutputStream(), true);
out.println("QUERY TIME ORDER");
System.out.println("Send order 2 server succeed.");
String resp = in.readLine();
System.out.println("Now is:" + resp);
} catch (Exception e) {
} finally {
if (out != null) {
out.close();
out = null;
}
if (in != null) {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
in = null;
}
if (socket != null) {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
socket = null;
}
}
}
}
分別執行服務端和客戶端,執行結果如下。智能推薦
Java NIO (一)
在現在,Java NIO已經越來越多的獲得了應用包括Tomcat,netty等,這項技術也由之前面試時候的加分項變成了Java程序員必備的技能之一。而之前我一直沒有系統的對其進行學習梳理,因此現在閑下來,想對這一塊的知識做一個相對完整的整理。話不多說,開始吧。 引 NIO主要有三大核心部分:Channel(通道),Buffer(緩沖區), Selector。傳統IO基于字節流和字符流進行操作,而N...
JAVA NIO入門一
1.簡介 2.什么是NIO 2.1 BIO Server: 服務端起來了之后,可以通過telnet 127.0.0.1 8080和服務端進行通信: 當然也可以自己寫個Client: BIO連接和線程對應關系: 引入線程池對客戶端連接進行處理: 雖然引入線程池極大的優化了BIO,但是線程池中的線程不可能無限制的增加,在高并發的情況下如果連接數量遠遠大于線程池中線程數量,那大于線程數量的請求就只能被阻...
Java NIO學習一
一、NIO概述 NIO即New IO,這個庫是在JDK1.4中才引入的。NIO和IO有相同的作用和目的,但實現方式不同,NIO主要用到的是塊,所以NIO的效率要比IO高很多。 NIO主要有三大核心部分:Channel(通道),Buffer(緩沖區), Selector。傳統IO基于字節流和字符流進行操作,而NIO基于Channel和Buffer(緩沖區)進行操作,數據總是從通道讀取到緩沖區中,或者...
Java NIO(一)
2019獨角獸企業重金招聘Python工程師標準>>> 原文地址:http://tutorials.jenkov.com/java-nio/index.html Java NIO(New IO)是一個可以替代標準Java IO API的IO API(從Java 1.4開始),Java NIO提供了與標準IO不同的IO工作方式。 Java NIO: Channels and Buf...
Netty4實戰第一章:Netty和Java NIO APIs
一、此章內容 Netty架構 為什么我們需要非阻塞IO(NIO) 阻塞IO和非阻塞IO對比 了解JDK NIO的問題和Netty的解決方案 這一章內容是要介紹Netty,不過大部分內容是介紹Java NIO接口。如果你是JVM網絡編程的新手,那么本章將是你學習網絡編程優秀的開端,對于經驗豐富的Java開發者,也可以令你復習到很多知識。對于有經驗的開發者來說,學習本章內容也是很好的復習...
猜你喜歡
Java NIO(五)Netty框架簡單應用
Netty是一款基于NIO開發的網絡通信框架,Netty能通過編程自定義各種協議,因為netty能夠通過自己來編碼/解碼字節流。本文只是對netty的簡單應用。。 關于Netty的一本書“Netty權威指南”,中提到了為什么要選擇Netty。 下面對上一篇文章中的Server/Client(客戶端向服務器端發送“query”字符串,服務器端響應給客戶...
freemarker + ItextRender 根據模板生成PDF文件
1. 制作模板 2. 獲取模板,并將所獲取的數據加載生成html文件 2. 生成PDF文件 其中由兩個地方需要注意,都是關于獲取文件路徑的問題,由于項目部署的時候是打包成jar包形式,所以在開發過程中時直接安照傳統的獲取方法沒有一點文件,但是當打包后部署,總是出錯。于是參考網上文章,先將文件讀出來到項目的臨時目錄下,然后再按正常方式加載該臨時文件; 還有一個問題至今沒有解決,就是關于生成PDF文件...
電腦空間不夠了?教你一個小秒招快速清理 Docker 占用的磁盤空間!
Docker 很占用空間,每當我們運行容器、拉取鏡像、部署應用、構建自己的鏡像時,我們的磁盤空間會被大量占用。 如果你也被這個問題所困擾,咱們就一起看一下 Docker 是如何使用磁盤空間的,以及如何回收。 docker 占用的空間可以通過下面的命令查看: TYPE 列出了docker 使用磁盤的 4 種類型: Images:所有鏡像占用的空間,包括拉取下來的鏡像,和本地構建的。 Con...
requests實現全自動PPT模板
http://www.1ppt.com/moban/ 可以免費的下載PPT模板,當然如果要人工一個個下,還是挺麻煩的,我們可以利用requests輕松下載 訪問這個主頁,我們可以看到下面的樣式 點每一個PPT模板的圖片,我們可以進入到詳細的信息頁面,翻到下面,我們可以看到對應的下載地址 點擊這個下載的按鈕,我們便可以下載對應的PPT壓縮包 那我們就開始做吧 首先,查看網頁的源代碼,我們可以看到每一...