欧美free性护士vide0shd,老熟女,一区二区三区,久久久久夜夜夜精品国产,久久久久久综合网天天,欧美成人护士h版

首頁綜合 正文
目錄

柚子快報激活碼778899分享:NIO 非阻塞式IO

柚子快報激活碼778899分享:NIO 非阻塞式IO

http://yzkb.51969.com/

NIO

Java NIO 基本介紹

Java NIO 全稱 Java non-blocking IO,是指 JDK 提供的新 API。從 JDK1.4 開始,Java 提供了一系列改進的輸入/輸出的新特性,被統(tǒng)稱為 NIO(即 NewIO),是同步非阻塞的。NIO 相關(guān)類都被放在 java.nio 包及子包下,并且對原 java.io 包中的很多類進行改寫。NIO 有三大核心部分:Channel(通道)、Buffer(緩沖區(qū))、Selector(選擇器) 。NIO 是面向緩沖區(qū),或者面向塊編程的。數(shù)據(jù)讀取到一個它稍后處理的緩沖區(qū),需要時可在緩沖區(qū)中前后移動,這就增加了處理過程中的靈活性,使用它可以提供非阻塞式的高伸縮性網(wǎng)絡(luò)。Java NIO 的非阻塞模式,使一個線程從某通道發(fā)送請求或者讀取數(shù)據(jù),但是它僅能得到目前可用的數(shù)據(jù),如果目前沒有數(shù)據(jù)可用時,就什么都不會獲取,而不是保持線程阻塞,所以直至數(shù)據(jù)變的可以讀取之前,該線程可以繼續(xù)做其他的事情。非阻塞寫也是如此,一個線程請求寫入一些數(shù)據(jù)到某通道,但不需要等待它完全寫入,這個線程同時可以去做別的事情。通俗理解:NIO 是可以做到用一個線程來處理多個操作的。假設(shè)有 10000 個請求過來,根據(jù)實際情況,可以分配 50 或者 100 個線程來處理。不像之前的阻塞 IO 那樣,非得分配 10000 個。HTTP 2.0 使用了多路復(fù)用的技術(shù),做到同一個連接并發(fā)處理多個請求,而且并發(fā)請求的數(shù)量比 HTTP 1.1 大了好幾個數(shù)量級。

NIO 三大核心原理示意圖

一張圖描述 NIO 的 Selector、Channel 和 Buffer 的關(guān)系。

每個 Channel 都會對應(yīng)一個 Buffer。Selector 對應(yīng)一個線程,一個線程對應(yīng)多個 Channel(連接)。該圖反應(yīng)了有三個 Channel 注冊到該 Selector //程序程序切換到哪個 Channel 是由事件決定的,Event 就是一個重要的概念。Selector 會根據(jù)不同的事件,在各個通道上切換。Buffer 就是一個內(nèi)存塊,底層是有一個數(shù)組。數(shù)據(jù)的讀取寫入是通過 Buffer,這個和 BIO是不同的,BIO 中要么是輸入流,或者是輸出流,不能雙向,但是 NIO 的 Buffer 是可以讀也可以寫,需要 flip 方法切換 Channel 是雙向的,可以返回底層操作系統(tǒng)的情況,比如 Linux,底層的操作系統(tǒng)通道就是雙向的。

NIO 和 BIO 的比較

BIO 以流的方式處理數(shù)據(jù),而 NIO 以塊的方式處理數(shù)據(jù),塊 I/O 的效率比流 I/O 高很多。 BIO 是阻塞的,NIO 則是非阻塞的。 BIO 基于字節(jié)流和字符流進行操作,而 NIO 基于 Channel(通道)和 Buffer(緩沖區(qū))進行操作,數(shù)據(jù)總是從通道讀取到緩沖區(qū)中,或者從緩沖區(qū)寫入到通道中。Selector(選擇器)用于監(jiān)聽多個通道的事件(比如:連接請求,數(shù)據(jù)到達等),因此使用單個線程就可以監(jiān)聽多個客戶端通道。 Buffer和Channel之間的數(shù)據(jù)流向是雙向的

緩沖區(qū)(Buffer)

緩沖區(qū)(Buffer):緩沖區(qū)本質(zhì)上是一個可以讀寫數(shù)據(jù)的內(nèi)存塊,可以理解成是一個**容器對象(含數(shù)組)**該對象提供了一組方法,可以更輕松地使用內(nèi)存塊,,緩沖區(qū)對象內(nèi)置了一些機制,能夠跟蹤和記錄緩沖區(qū)的狀態(tài)變化情況。Channel 提供從文件、網(wǎng)絡(luò)讀取數(shù)據(jù)的渠道,但是讀取或?qū)懭氲臄?shù)據(jù)都必須經(jīng)由 Buffer,

通道(Channel)

NIO 的通道類似于流,但有些區(qū)別如下:

通道可以同時進行讀寫,而流只能讀或者只能寫通道可以實現(xiàn)異步讀寫數(shù)據(jù)通道可以從緩沖讀數(shù)據(jù),也可以寫數(shù)據(jù)到緩沖:

BIO 中的 Stream 是單向的,例如 FileInputStream 對象只能進行讀取數(shù)據(jù)的操作,而 NIO 中的通道(Channel)是雙向的,可以讀操作,也可以寫操作。Channel 在 NIO 中是一個接口 public interface Channel extends Closeable{}常用的 Channel 類有:FileChannel、DatagramChannel、ServerSocketChannel 和 SocketChannel?!維erverSocketChanne 類似 ServerSocket、SocketChannel 類似 Socket】FileChannel 用于文件的數(shù)據(jù)讀寫,DatagramChannel 用于 UDP 的數(shù)據(jù)讀寫,ServerSocketChannel 和 SocketChannel 用于 TCP 的數(shù)據(jù)讀寫。

NIO 還支持通過多個 Buffer(即 Buffer數(shù)組)完成讀寫操作,即 Scattering 和 Gathering【舉例說明】

/**

* @Author:jiangdw7

* @date: 2023/8/9 10:04

*/

public class ScatteringAndGatheringTest {

public static void main(String[] args) throws Exception {

//使用 ServerSocketChannel 和 SocketChannel 網(wǎng)絡(luò)

ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();

InetSocketAddress inetSocketAddress = new InetSocketAddress(7000);

//綁定端口到 socket,并啟動

serverSocketChannel.socket().bind(inetSocketAddress);

//創(chuàng)建 buffer 數(shù)組

ByteBuffer[] byteBuffers = new ByteBuffer[2];

byteBuffers[0] = ByteBuffer.allocate(5);

byteBuffers[1] = ByteBuffer.allocate(3);

//等客戶端連接 (telnet)

SocketChannel socketChannel = serverSocketChannel.accept();

int messageLength = 8; //假定從客戶端接收 8 個字節(jié)

//循環(huán)的讀取

while (true) {

int byteRead = 0;

while (byteRead < messageLength) {

long l = socketChannel.read(byteBuffers);

byteRead += l; //累計讀取的字節(jié)數(shù)

System.out.println("byteRead = " + byteRead);

//使用流打印,看看當(dāng)前的這個 buffer 的 position 和 limit

Arrays.asList(byteBuffers).stream().map(buffer -> "position = " + buffer.position() + ", limit = " + buffer.limit()).forEach(System.out::println);

}

//將所有的 buffer 進行 flip

Arrays.asList(byteBuffers).forEach(buffer -> buffer.flip());

//將數(shù)據(jù)讀出顯示到客戶端

long byteWirte = 0;

while (byteWirte < messageLength) {

long l = socketChannel.write(byteBuffers);

byteWirte += l;

}

//將所有的buffer進行clear

Arrays.asList(byteBuffers).forEach(buffer -> {

buffer.clear();

});

System.out.println("byteRead = " + byteRead + ", byteWrite = " + byteWirte + ", messagelength = " + messageLength);

}

}

}

Selector(選擇器)

Java 的 NIO,用非阻塞的 IO 方式??梢杂靡粋€線程,處理多個的客戶端連接,就會使用到 Selector(選擇器)。Selector 能夠檢測多個注冊的通道上是否有事件發(fā)生(注意:多個 Channel 以事件的方式可以注冊到同一個 Selector),如果有事件發(fā)生,便獲取事件然后針對每個事件進行相應(yīng)的處理。這樣就可以只用一個單線程去管理多個通道,也就是管理多個連接和請求。只有在連接/通道真正有讀寫事件發(fā)生時,才會進行讀寫,就大大地減少了系統(tǒng)開銷,并且不必為每個連接都創(chuàng)建一個線程,不用去維護多個線程。避免了多線程之間的上下文切換導(dǎo)致的開銷。

注意事項

NIO 中的 ServerSocketChannel 功能類似 ServerSocket、SocketChannel 功能類似 Socket。Selector 相關(guān)方法說明

selector.select(); //阻塞selector.select(1000); //阻塞 1000 毫秒,在 1000 毫秒后返回selector.wakeup(); //喚醒 selectorselector.selectNow(); //不阻塞,立馬返還

public class NIOClient {

private static Selector selector;

public static void main(String[] args) throws Exception {

selector = Selector.open();

SocketChannel sc = SocketChannel.open();

sc.configureBlocking(false);

sc.connect(new InetSocketAddress("127.0.0.1", 8081));

sc.register(selector, SelectionKey.OP_READ);

ByteBuffer bf = ByteBuffer.allocate(1024);

bf.put("Hi,server,i'm client".getBytes());

if (sc.finishConnect()) {

bf.flip();

while (bf.hasRemaining()) {

sc.write(bf);

}

while (sc.isConnected()) {

selector.select();

Iterator it = selector.selectedKeys().iterator();

while (it.hasNext()) {

SelectionKey key = it.next();

if (key.isReadable()) {

ByteArrayOutputStream bos = new ByteArrayOutputStream();

bf.clear();

SocketChannel othersc = (SocketChannel) key.channel();

while (othersc.read(bf) > 0) {

bf.flip();

while (bf.hasRemaining()) {

bos.write(bf.get());

}

bf.clear();

}

System.out.println("服務(wù)端返回的數(shù)據(jù):" + bos.toString());

Thread.sleep(5000);

sc.close();

System.out.println("客戶端關(guān)閉...");

}

}

selector.selectedKeys().clear();

}

}

}

}

public class NIOServer {

private static Selector selector;

private static ServerSocketChannel serverSocketChannel;

private static ByteBuffer bf = ByteBuffer.allocate(1024);

public static void main(String[] args) throws Exception {

init();

while (true) {

int select = selector.select(10000);

if (select == 0) {

System.out.println("等待連接10秒...");

continue;

}

Iterator it = selector.selectedKeys().iterator();

while (it.hasNext()) {

SelectionKey key = it.next();

if (key.isAcceptable()) {

System.out.println("連接準備就緒");

ServerSocketChannel server = (ServerSocketChannel) key.channel();

System.out.println("等待客戶端連接中........................");

SocketChannel channel = server.accept();

channel.configureBlocking(false);

channel.register(selector, SelectionKey.OP_READ);

} else if (key.isReadable()) {

System.out.println("讀準備就緒,開始讀.......................");

SocketChannel channel = (SocketChannel) key.channel();

System.out.println("客戶端的數(shù)據(jù)如下:");

int readLen = 0;

bf.clear();

StringBuffer sb = new StringBuffer();

while ((readLen = channel.read(bf)) > 0) {

bf.flip();

byte[] temp = new byte[readLen];

bf.get(temp, 0, readLen);

sb.append(new String(temp));

bf.clear();

}

if (-1 == readLen) {

System.out.println(channel.hashCode()+"號客戶端關(guān)閉。");

channel.close();

}else {

channel.write(ByteBuffer.wrap(("客戶端,你傳過來的數(shù)據(jù)是:" + sb.toString()).getBytes()));

System.out.println(sb.toString()+"132123");

}

}

it.remove();

}

}

}

private static void init() throws Exception {

selector = Selector.open();

serverSocketChannel = ServerSocketChannel.open();

serverSocketChannel.configureBlocking(false);

serverSocketChannel.socket().bind(new InetSocketAddress(8081));

serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);

}

}

參考連接

https://www.cnblogs.com/xdouby/p/8942083.html

https://www.zhihu.com/question/22524908

https://blog.csdn.net/ArtAndLife/article/details/121001656

AIO

JDK7 引入了 AsynchronousI/O,即 AIO。在進行 I/O 編程中,常用到兩種模式:Reactor 和 Proactor。Java 的 NIO 就是 Reactor,當(dāng)有事件觸發(fā)時,服務(wù)器端得到通知,進行相應(yīng)的處理 AIO 即 NIO2.0,叫做異步不阻塞的 IO。AIO 引入異步通道的概念,采用了 Proactor 模式,簡化了程序編寫,有效的請求才啟動線程,它的特點是先由操作系統(tǒng)完成后才通知服務(wù)端程序啟動線程去處理,一般適用于連接數(shù)較多且連接時間較長的應(yīng)用 目前 AIO 還沒有廣泛應(yīng)用,Netty 也是基于 NIO,而不是 AIO,因此我們就不詳解 AIO 了,有興趣的同學(xué)可以參考《Java新一代網(wǎng)絡(luò)編程模型AIO原理及Linux系統(tǒng)AIO介紹》

柚子快報激活碼778899分享:NIO 非阻塞式IO

http://yzkb.51969.com/

推薦閱讀

評論可見,查看隱藏內(nèi)容

本文內(nèi)容根據(jù)網(wǎng)絡(luò)資料整理,出于傳遞更多信息之目的,不代表金鑰匙跨境贊同其觀點和立場。

轉(zhuǎn)載請注明,如有侵權(quán),聯(lián)系刪除。

本文鏈接:http://gantiao.com.cn/post/17829725.html

發(fā)布評論

您暫未設(shè)置收款碼

請在主題配置——文章設(shè)置里上傳

掃描二維碼手機訪問

文章目錄