Java BIO編程
標簽: Netty核心技術及源碼剖析 I/O模型 NIO Netty BIO RPC
1. I/O 模型
1.1. I/O 模型基本說明
- I/O 模型簡單的理解:就是用什么樣的通道進行數據的發送和接收,很大程度上決定了程序通信的性能
- Java 共支持 3 種網絡編程模型/IO 模式:BIO、NIO、AIO
- Java BIO : 同步并阻塞(傳統阻塞型),服務器實現模式為一個連接一個線程,即客戶端有連接請求時服務器
端就需要啟動一個線程進行處理,如果這個連接不做任何事情會造成不必要的線程開銷 【簡單示意圖】
- Java NIO : 同步非阻塞,服務器實現模式為一個線程處理多個請求(連接),即客戶端發送的連接請求都會注
冊到多路復用器上,多路復用器輪詢到連接有 I/O 請求就進行處理 【簡單示意圖】
- Java AIO(NIO.2) : 異步非阻塞,AIO 引入異步通道的概念,采用了 Proactor 模式,簡化了程序編寫,有效的請求才啟動線程,它的特點是先由操作系統完成后才通知服務端程序啟動線程去處理,一般適用于連接數較多且連接時間較長的應用。
1.2. BIO、NIO、AIO 適用場景分析
- BIO 方式適用于連接數目比較小且固定的架構,這種方式對服務器資源要求比較高,并發局限于應用中,JDK1.4以前的唯一選擇,但程序簡單易理解。
- NIO 方式適用于連接數目多且連接比較短(輕操作)的架構,比如聊天服務器,彈幕系統,服務器間通訊等。編程比較復雜,JDK1.4 開始支持。
- AIO 方式使用于連接數目多且連接比較長(重操作)的架構,比如相冊服務器,充分調用 OS 參與并發操作,
編程比較復雜,JDK7 開始支持。
1.3. Java BIO 基本介紹
- Java BIO 就是傳統的 java io 編程,其相關的類和接口在java.io
- BIO(blocking I/O) : 同步阻塞,服務器實現模式為一個連接一個線程,即客戶端有連接請求時服務器端就需要啟動一個線程進行處理,如果這個連接不做任何事情會造成不必要的線程開銷,可以通過線程池機制改善(實現多個客戶連接服務器)。
- BIO 方式適用于連接數目比較小且固定的架構,這種方式對服務器資源要求比較高,并發局限于應用中,JDK1.4以前的唯一選擇,程序簡單易理解
1.4. Java BIO 工作機制
對 BIO 編程流程的梳理
- 服務器端啟動一個 ServerSocket
- 客戶端啟動 Socket 對服務器進行通信,默認情況下服務器端需要對每個客戶 建立一個線程與之通訊
- 客戶端發出請求后, 先咨詢服務器是否有線程響應,如果沒有則會等待,或者被拒絕
- 如果有響應,客戶端線程會等待請求結束后,在繼續執行
1.5. Java BIO 應用實例
實例說明:
- 使用 BIO 模型編寫一個服務器端,監聽 6666 端口,當有客戶端連接時,就啟動一個線程與之通訊。
- 要求使用線程池機制改善,可以連接多個客戶端。
- 服務器端可以接收客戶端發送的數據(telnet 方式即可)。
- 代碼演示:
package com.mylove.bio;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* @program: NettyPro
* @description: BIO服務端
* @author: XXXXX
* @create: 2020-09-08 20:31
**/
public class BIOServer {
public static void main(String[] args) throws IOException {
//思路
//1. 創建一個線程池
//2.如果有客戶端連接,就創建一個線程與之通訊
ExecutorService newCachedThreadPool = Executors.newCachedThreadPool();
//創建ServerSocket
ServerSocket serverSocket = new ServerSocket(6666);
System.out.println("服務器啟動了");
while(true){
System.out.println("等待連接....");
final Socket socket = serverSocket.accept();
System.out.println("連接到一個客戶端");
newCachedThreadPool.execute(new Runnable() {
public void run() {
handler(socket);
}
});
}
}
public static void handler(Socket socket){
try {
System.out.println("線程信息 id = " + Thread.currentThread().getId() +" 線程名字 = " + Thread.currentThread().getName());
byte[] bytes = new byte[1024];
InputStream inputStream = socket.getInputStream();
while (true){
System.out.println(" 線 程 信 息 id =" + Thread.currentThread().getId() + " 名 字 =" +
Thread.currentThread().getName());
System.out.println("read....");
int read = inputStream.read(bytes);
if(read != -1){
System.out.println(new String(bytes,0,read));
}else{
break;
}
}
} catch (IOException e) {
e.printStackTrace();
}finally {
System.out.println("關閉和client的連接");
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
- 啟動main方法,同時啟動CMD命令行,在窗口中輸入 telent 127.0.0.1 6666,然后輸入 Ctrl + ] (Ctrl鍵和 ] 組合鍵),接著在窗口中輸入 send + “要發送的字符串”,在BIO的服務端即可接收到數據:
1.6. Java BIO 問題分析
- 每個請求都需要創建獨立的線程,與對應的客戶端進行數據 Read,業務處理,數據 Write 。
- 當并發數較大時,需要創建大量線程來處理連接,系統資源占用較大。
- 連接建立后,如果當前線程暫時沒有數據可讀,則線程就阻塞在 Read 操作上,造成線程資源浪費
智能推薦
JAVA原生JDK網絡編程 BIO/NIO
1 原生 JDK 網絡編程 BIO 傳統的同步阻塞模型開發中,ServerSocket 負責綁定 IP 地址,啟動監聽端口;Socket 負責發起連接操作。連接成功后,雙方通過輸入和輸出流進行同步阻塞式通信。傳統 BIO 通信模型:采用 BIO 通信模型的服務端,通常由一個獨立的 Acceptor 線程負責監聽客戶端的連接,它接收到客戶端連接請求之后為每個客戶端創建一個新的線程進行鏈路處理,處理完...
Java網絡編程 -- BIO 阻塞式網絡編程
阻塞IO的含義 阻塞(blocking)IO :阻塞是指結果返回之前,線程會被掛起,函數只有在得到結果之后(或超時)才會返回 非阻塞(non-blocking)IO :非阻塞和阻塞的概念相對應,指在不能立刻得到結果之前,該函數不會阻塞當前線程,而會立刻返回 同步(synchronous)IO :應用阻塞在發送或接受數據的狀態,直至數據成功傳輸(或返回失敗),簡單來說就是必須一件一件事做,等前一件做...
Java 網絡編程----回顧傳統網絡編程BIO
一.介紹 1.1 網絡編程的基本模型是Client/Server模型,也就是兩個進程直接進行相互通信,其中服務端提供配置信息(綁定的IP地址和監聽端口),客戶端通過連接操作向服務端監聽的地址發起連接請求,通過三次握手建立連接,如果連接成功,則雙方即可以進行通信(網絡套接字Socket).模型如下圖所示 &n...
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壓縮包 那我們就開始做吧 首先,查看網頁的源代碼,我們可以看到每一...
Linux C系統編程-線程互斥鎖(四)
互斥鎖 互斥鎖也是屬于線程之間處理同步互斥方式,有上鎖/解鎖兩種狀態。 互斥鎖函數接口 1)初始化互斥鎖 pthread_mutex_init() man 3 pthread_mutex_init (找不到的情況下首先 sudo apt-get install glibc-doc sudo apt-get install manpages-posix-dev) 動態初始化 int pthread_...
統計學習方法 - 樸素貝葉斯
引入問題:一機器在良好狀態生產合格產品幾率是 90%,在故障狀態生產合格產品幾率是 30%,機器良好的概率是 75%。若一日第一件產品是合格品,那么此日機器良好的概率是多少。 貝葉斯模型 生成模型與判別模型 判別模型,即要判斷這個東西到底是哪一類,也就是要求y,那就用給定的x去預測。 生成模型,是要生成一個模型,那就是誰根據什么生成了模型,誰就是類別y,根據的內容就是x 以上述例子,判斷一個生產出...