国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

【JAVA基礎(chǔ)】- 同步非阻塞模式NIO詳解

這篇具有很好參考價值的文章主要介紹了【JAVA基礎(chǔ)】- 同步非阻塞模式NIO詳解。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

【JAVA基礎(chǔ)】- 同步非阻塞模式NIO詳解

一、概述

NIO(Non-Blocking IO)是同步非阻塞方式來處理IO數(shù)據(jù)。服務(wù)器實現(xiàn)模式為一個請求一個線程,即客戶端發(fā)送的鏈接請求都會注冊到選擇器上,選擇器輪詢到連接有IO請求時才啟動一個線程進(jìn)行處理。

二、常用概念

  • 同步(synchronous):調(diào)用方式指應(yīng)用(Application),調(diào)用方發(fā)起有一個功能調(diào)用時,在沒有得到功能的結(jié)果之前,該調(diào)用不會返回。也就是說調(diào)用方會一直等待被調(diào)用方返回功能的結(jié)果。
  • 異步(asynchronous):調(diào)用方發(fā)起一個功能調(diào)用時,沒有得到功能的結(jié)果立即返回,后續(xù)被調(diào)用方再通過回調(diào)等手段,把功能的結(jié)構(gòu)通知調(diào)用方。也就是調(diào)用方立即得到返回,但是返回中不包含執(zhí)行的結(jié)果。

同步和異步強(qiáng)調(diào)的是消息通信機(jī)制 (synchronous communication/ asynchronous communication)。所謂同步,就是在發(fā)出一個"調(diào)用"時,在沒有得到結(jié)果之前,該“調(diào)用”就不返回。但是一旦調(diào)用返回,就得到返回值了。換句話說,就是由“調(diào)用者”主動等待這個“調(diào)用”的結(jié)果。而異步則是相反,"調(diào)用"在發(fā)出之后,這個調(diào)用就直接返回了,所以沒有返回結(jié)果。換句話說,當(dāng)一個異步過程調(diào)用發(fā)出后,調(diào)用者不會立刻得到結(jié)果。而是在"調(diào)用"發(fā)出后,"被調(diào)用者"通過狀態(tài)、通知來通知調(diào)用者,或通過回調(diào)函數(shù)處理這個調(diào)用

  • 阻塞:線程發(fā)起一個調(diào)用時, 在調(diào)用返回之前, 線程會被阻塞, 在這個狀態(tài)下會交出當(dāng)前CPU的使用權(quán)而暫停;也就是調(diào)用方會等待調(diào)用結(jié)果, 調(diào)用阻塞了調(diào)用方的線程, 線程不在運(yùn)行處理中。
  • 非阻塞:線程發(fā)起一個調(diào)用時, 調(diào)用會立即返回, 避免線程被阻塞。但是, 返回的結(jié)果只是被調(diào)用方當(dāng)前狀態(tài)的值, 實際使用時, 調(diào)用方需要輪詢, 直到返回結(jié)果符合預(yù)期(直到數(shù)據(jù)準(zhǔn)備好)。

阻塞和非阻塞 強(qiáng)調(diào)的是程序在等待調(diào)用結(jié)果(消息,返回值)時的狀態(tài). 阻塞調(diào)用是指調(diào)用結(jié)果返回之前,當(dāng)前線程會被掛起。調(diào)用線程只有在得到結(jié)果之后才會返回。非阻塞調(diào)用指在不能立刻得到結(jié)果之前,該調(diào)用不會阻塞當(dāng)前線程。 對于同步調(diào)用來說,很多時候當(dāng)前線程還是激活的狀態(tài),只是從邏輯上當(dāng)前函數(shù)沒有返回而已,即同步等待時什么都不干,白白占用著資源。

  • 同步阻塞 IO[BIO - BlockingIO]:在此種方式下,用戶進(jìn)程在發(fā)起一個 IO 操作以后,必須等待 IO 操作的完成,只有當(dāng)真正完成了 IO 操作以后,用戶進(jìn)程才能運(yùn)行。 JAVA傳統(tǒng)的 IO 模型屬于此種方式。
  • 同步非阻塞 IO[Non-Blocking IO]:在此種方式下,用戶進(jìn)程發(fā)起一個 IO 操作以后 邊可 返回做其它事情,但是用戶進(jìn)程需要時不時的詢問 IO 操作是否就緒,這就要求用戶進(jìn)程不停的去詢問,從而引入不必要的 CPU 資源浪費(fèi)。其中目前 JAVA 的 NIO 就屬于同步非阻塞 IO 。
  • 異步阻塞 IO[IO Multiplexing]:此種方式下是指應(yīng)用發(fā)起一個 IO 操作以后,不等待內(nèi)核 IO 操作的完成,等內(nèi)核完成 IO 操作以后會通知應(yīng)用程序,這其實就是同步和異步最關(guān)鍵的區(qū)別,同步必須等待或者主動的去詢問 IO 是否完成,那么為什么說是阻塞的呢?因為此時是通過 select 系統(tǒng)調(diào)用來完成的,而 select 函數(shù)本身的實現(xiàn)方式是阻塞的,而采用 select 函數(shù)有個好處就是它可以同時監(jiān)聽多個文件句柄,從而提高系統(tǒng)的并發(fā)性!
  • 異步非阻塞 IO[Asynchronous IO]: 在此種模式下,用戶進(jìn)程只需要發(fā)起一個 IO 操作然后立即返回,等 IO 操作真正的完成以后,應(yīng)用程序會得到 IO 操作完成的通知,此時用戶進(jìn)程只需要對數(shù)據(jù)進(jìn)行處理就好了,不需要進(jìn)行實際的 IO 讀寫操作,因為 真正的 IO讀取或者寫入操作已經(jīng)由 內(nèi)核完成了。目前 Java 中還沒有支持此種 IO 模型。

三、NIO的實現(xiàn)原理

【JAVA基礎(chǔ)】- 同步非阻塞模式NIO詳解,JAVA,java,nio

Java的NIO主要由三個核心部分組成:Channel(通道)、Buffer(緩沖區(qū))、Selector

所有的IO在NIO中都從一個Channel開始,數(shù)據(jù)可以從Channel讀到Buffer中,也可以從Buffer寫到Channel中。Channel有好幾種類型,其中比較常用的有FileChannel、DatagramChannel、SocketChannelServerSocketChannel等,這些通道涵蓋了UDP和TCP網(wǎng)絡(luò)IO以及文件IO。

Buffer本質(zhì)上是一塊可以寫入數(shù)據(jù),然后可以從中讀取數(shù)據(jù)的內(nèi)存。這塊內(nèi)存被包裝成NIO Buffer對象,并提供了一組方法,用來方便的訪問該塊內(nèi)存。Java NIO里關(guān)鍵的Buffer實現(xiàn)有CharBuffer、ByteBuffer、ShortBufferIntBuffer、LongBufferFloatBuffer、DoubleBuffer。這些Buffer覆蓋了你能通過IO發(fā)送的基本數(shù)據(jù)類型,即byte、shortint、long、float、double、char。

Buffer對象包含三個重要的屬性,分別是capacity、position、limit,其中position和limit的含義取決于Buffer處在讀模式還是寫模式。但不管Buffer處在什么模式,capacity的含義總是一樣的。

capacity:作為一個內(nèi)存塊,Buffer有個固定的最大值,就是capacity。Buffer只能寫capacity個數(shù)據(jù),一旦Buffer滿了,需要將其清空才能繼續(xù)寫數(shù)據(jù)往里寫數(shù)據(jù)。

position:當(dāng)寫數(shù)據(jù)到Buffer中時,position表示當(dāng)前的位置。初始的position值為0。當(dāng)一個數(shù)據(jù)寫到Buffer后, position會向前移動到下一個可插入數(shù)據(jù)的Buffer單元。position最大可為capacity–1。當(dāng)讀取數(shù)據(jù)時,也是從某個特定位置讀。當(dāng)將Buffer從寫模式切換到讀模式,position會被重置為0。當(dāng)從Buffer的position處讀取數(shù)據(jù)時,position向前移動到下一個可讀的位置。

limit:在寫模式下,Buffer的limit表示最多能往Buffer里寫多少數(shù)據(jù),此時limit等于capacity。當(dāng)切換Buffer到讀模式時, limit表示你最多能讀到多少數(shù)據(jù),此時limit會被設(shè)置成寫模式下的position值。

Selector允許單線程處理多個 Channel,如果你的應(yīng)用打開了多個連接(通道),但每個連接的流量都很低,使用Selector就會很方便。要使用Selector,得向Selector注冊Channel,然后調(diào)用它的select()方法。這個方法會一直阻塞到某個注冊的通道有事件就緒。一旦這個方法返回,線程就可以處理這些事件,事件例如有新連接進(jìn)來,數(shù)據(jù)接收等。

四、NIO代碼實現(xiàn)

客戶端實現(xiàn)
  • 步驟

    1. 創(chuàng)建SocketChannel 通道
    2. 切換異步非阻塞模式configureBlocking(false)
    3. 設(shè)置緩沖區(qū)大小ByteBuffer.allocate(1024)
    4. 值寫入緩沖區(qū) buffer.put(input.getBytes())
    5. 緩沖區(qū)中的值寫入通道中channel.write()
  • 代碼演示

    public static void main(String[] args) throws IOException {
          //創(chuàng)建通道
          SocketChannel channel=SocketChannel.open(new InetSocketAddress("127.0.0.1",6001));
          //切換異步非阻塞模式
          channel.configureBlocking(false);
          //設(shè)置緩沖去大小
          ByteBuffer buffer=ByteBuffer.allocate(1024);
          System.out.println("輸入傳輸值:");
          //獲取鍵盤輸入的值
          Scanner scanner = new Scanner(System.in);
          while (scanner.hasNext()){
              String input=scanner.next();
              //把獲取的值寫入緩沖區(qū)中
              buffer.put(input.getBytes());
              buffer.flip();
              //把緩沖區(qū)中的值寫入通道中
              channel.write(buffer);
              buffer.clear();
           }
           channel.close();
     }
    
服務(wù)端實現(xiàn)
  • 步驟

    1. 創(chuàng)建ServerSocketChannel通道
    2. 切換異步非阻塞模式configureBlocking(false)
    3. 綁定連接
    4. 獲取選擇器 Selector open = Selector.open()
    5. 將通道注冊到選擇器,并指定監(jiān)聽接受事件
    6. 輪訓(xùn)式獲取選擇已準(zhǔn)備就緒的事件
    7. 獲取當(dāng)前選擇器所有注冊的監(jiān)聽事件
    8. 獲取準(zhǔn)備就緒的事件
    9. 判斷是什么事件準(zhǔn)備就緒
    10. 接受就緒,獲取客戶端連接
    11. 設(shè)置非阻塞異步模式
    12. 將通道注冊到服務(wù)器上
  • 代碼演示

    public static void main(String[] args) throws IOException {
        //創(chuàng)建通道
        ServerSocketChannel channel=ServerSocketChannel.open();
        //切換到異步非阻塞模式
        channel.configureBlocking(false);
        //綁定鏈接
        channel.bind(new InetSocketAddress(6001));
            //獲取選擇器
            Selector open = Selector.open();
            //將通道注冊到選擇器,并指定監(jiān)聽接受事件
            channel.register(open, SelectionKey.OP_ACCEPT);
            //輪訓(xùn)式獲取選擇已經(jīng)準(zhǔn)備就緒的事件
            while(open.select() > 0) {
                //獲取當(dāng)前選擇器所有注冊的監(jiān)聽事件
                Iterator<SelectionKey> it = open.selectedKeys().iterator();
                while(it.hasNext()) {
                    //獲取準(zhǔn)備就緒的事件
                    SelectionKey sk = it.next();
                    //判斷是什么事件準(zhǔn)備就緒
                    if(sk.isAcceptable()) {
                        //接受就緒,獲取客戶端連接
                        SocketChannel sc = channel.accept();
                        //設(shè)置非阻塞異步模式
                        sc.configureBlocking(false);
                        //將通道注冊到服務(wù)器上
                        sc.register(open, SelectionKey.OP_READ);
                    } else if(sk.isReadable()) {
                        //獲取當(dāng)前選擇器就緒的通道
                        SocketChannel s =  (SocketChannel) sk.channel();
                        ByteBuffer bb = ByteBuffer.allocate(1024);
                        int len = 0;
                        while((len = s.read(bb)) > 0) {
                            bb.flip();
                            System.out.println(new String(bb.array(),0,len));
                            bb.clear();
                        }
                   }
              }
             it.remove();
         }
    
    }
    

五、同步非阻塞NIO總結(jié)

同步非阻塞的特點:應(yīng)用程序的線程需要不斷的進(jìn)行IO系統(tǒng)調(diào)用,輪詢數(shù)據(jù)是否已經(jīng)準(zhǔn)備好,如果沒有準(zhǔn)備好,就繼續(xù)輪詢,直到完成IO系統(tǒng)調(diào)用為止。

同步非阻塞IO的特點:每次發(fā)起的IO系統(tǒng)調(diào)用,在內(nèi)核等待數(shù)據(jù)過程中可以立即返回。用戶線程不會被阻塞,實時性較好。

同步非阻塞IO的缺點: 不斷地輪詢內(nèi)核,這將占用大量的CPU時間,效率低下。

總體來說,在高并發(fā)應(yīng)用場景下,同步非阻塞IO也是不可用的。一般Web服務(wù)器不適用這種IO模型。這種IO模型一般很少直接使用,而是在其他IO模型中使用非阻塞IO這一特性。文章來源地址http://www.zghlxwxcb.cn/news/detail-647960.html

到了這里,關(guān)于【JAVA基礎(chǔ)】- 同步非阻塞模式NIO詳解的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進(jìn)行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • JAVA NIO概念詳解

    Java NIO(New I/O)是Java平臺提供的一組用于高效處理I/O操作的API。相較于傳統(tǒng)的Java I/O(java.io)API,Java NIO提供了更加靈活、高效的非阻塞I/O操作方式。主要一些概念如下。 Java NIO中的I/O操作是基于緩沖區(qū)的。緩沖區(qū)實質(zhì)上是一個固定大小的內(nèi)存塊,用于存儲數(shù)據(jù)。它可以作為

    2024年02月09日
    瀏覽(37)
  • JAVA的BIO、NIO、AIO模式精解(一)

    JAVA的BIO、NIO、AIO模式精解(一)

    在不同系統(tǒng)或進(jìn)程間數(shù)據(jù)交互,或高并發(fā)場景下都選喲網(wǎng)絡(luò)通信。早期是基于性能低下的同步阻塞IO(BIO)實現(xiàn)。后支持非阻塞IO(NIO)。 前置須知:javsse,java多線程,javaIO,java網(wǎng)絡(luò)模型 目的:局域網(wǎng)內(nèi)通信,多系統(tǒng)間底層消息傳遞機(jī)制,高并發(fā)下大數(shù)據(jù)通信,游戲應(yīng)用。 IO模型

    2023年04月27日
    瀏覽(23)
  • Java-NIO篇章(4)——Reactor反應(yīng)器模式

    Java-NIO篇章(4)——Reactor反應(yīng)器模式

    前面已經(jīng)講過了Java-NIO中的三大核心組件Selector、Channel、Buffer,現(xiàn)在組件我們回了,但是如何實現(xiàn)一個超級高并發(fā)的socket網(wǎng)絡(luò)通信程序呢?假設(shè),我們只有一臺內(nèi)存為32G的Intel-i710八核的機(jī)器,如何實現(xiàn)同時2萬個客戶端高并發(fā)非阻塞通信?可能你會說不可能實現(xiàn),答案是2萬的

    2024年01月22日
    瀏覽(30)
  • 快速入門java網(wǎng)絡(luò)編程基礎(chǔ)------Nio

    快速入門java網(wǎng)絡(luò)編程基礎(chǔ)------Nio

    嗶哩嗶哩黑馬程序員 netty實戰(zhàn)視頻 NIO(New I/O)是Java中提供的一種基于通道和緩沖區(qū)的I/O(Input/Output)模型。它是相對于傳統(tǒng)的IO(InputStream和OutputStream)模型而言的新型I/O模型。NIO的主要特點包括: 1.通道與緩沖區(qū): 2.NIO引入了通道(Channel)和緩沖區(qū)(Buffer)的概念。通道

    2024年01月20日
    瀏覽(29)
  • Java NIO全面詳解(看這篇就夠了)

    Java NIO全面詳解(看這篇就夠了)

    很多技術(shù)框架都使用NIO技術(shù),學(xué)習(xí)和掌握J(rèn)ava NIO技術(shù)對于高性能、高并發(fā)網(wǎng)絡(luò)的應(yīng)用是非常關(guān)鍵的@mikechen NIO 中的 N 可以理解為 Non-blocking,不單純是 New,是解決高并發(fā)、I/O高性能的有效方式。 Java NIO是Java1.4之后推出來的一套IO接口,NIO提供了一種完全不同的操作方式, NIO支持

    2024年04月27日
    瀏覽(18)
  • Java NIO Files類讀取文件流方式詳解

    java.nio.file.Files 是Java標(biāo)準(zhǔn)庫提供的一個工具類,用于操作文件和目錄。它提供了一系列靜態(tài)方法,可以用于創(chuàng)建、復(fù)制、刪除、移動、重命名、讀取、寫入文件和目錄等常見的文件系統(tǒng)操作。同時,它也提供了一些高級特性,如文件系統(tǒng)監(jiān)控、文件屬性操作等。在Java 7中引入

    2024年02月15日
    瀏覽(25)
  • Java-NIO篇章(4)——Selector選擇器詳解

    Java-NIO篇章(4)——Selector選擇器詳解

    選擇器(Selector)是什么呢?選擇器和通道的關(guān)系又是什么?這里詳細(xì)說明,假設(shè)不用選擇器,那么一個客戶端請求數(shù)據(jù)傳輸那就需要建立一個連接,為了避免線程阻塞,那么每個客戶端開辟一個線程。而學(xué)過JVM的都知道,默認(rèn)每開一個線程需要??臻g內(nèi)存1MB大小。如果這時

    2024年01月21日
    瀏覽(31)
  • Java-NIO篇章(3)——Channel通道類詳解

    Java NIO中,一個socket連接使用一個Channel(通道)來表示。對應(yīng)到不同的網(wǎng)絡(luò)傳輸協(xié)議類型,在Java中都有不同的NIO Channel(通道) 相對應(yīng)。其中最為重要的四種Channel(通道)實現(xiàn): FileChannel、 SocketChannel、 ServerSocketChannel、 DatagramChannel : FileChannel 文件通道,用于文件的數(shù)據(jù)讀

    2024年01月20日
    瀏覽(23)
  • 【Java基礎(chǔ)】BIO/NIO/AIO的詳細(xì)介紹與比較區(qū)分

    【Java基礎(chǔ)】BIO/NIO/AIO的詳細(xì)介紹與比較區(qū)分

    BIO 全稱 Blocking I/O,它是 JDK 1.4 之前的傳統(tǒng)IO模型,是一種同步阻塞的IO,線程發(fā)起 IO 后,一直阻塞,直到緩沖區(qū)數(shù)據(jù)就緒后,在進(jìn)入下一步操作 BIO存在的問題: 無法應(yīng)對高并發(fā)的場景 連接建立后,當(dāng)前線程沒有數(shù)據(jù)可讀就會阻塞,造成資源浪費(fèi) BIO適用場景: 客戶端連接數(shù)

    2024年01月20日
    瀏覽(26)
  • NIO 非阻塞式IO

    NIO 非阻塞式IO

    Java NIO 基本介紹 Java NIO 全稱 Java non-blocking IO ,是指 JDK 提供的新 API 。從 JDK1.4 開始, Java 提供了一系列改進(jìn)的輸入/輸出的新特性,被統(tǒng)稱為 NIO (即 NewIO ),是同步非阻塞的。 NIO 相關(guān)類都被放在 java.nio 包及子包下,并且對原 java.io 包中的很多類進(jìn)行改寫。 NIO 有三大核心

    2024年02月13日
    瀏覽(44)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包