Java同步阻塞怎么實現

本篇內容介紹了“Java同步阻塞怎么實現”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!

成都創(chuàng)新互聯專業(yè)為企業(yè)提供南充網站建設、南充做網站、南充網站設計、南充網站制作等企業(yè)網站建設、網頁設計與制作、南充企業(yè)網站模板建站服務,十余年南充做網站經驗,不只是建網站,更提供有價值的思路和整體網絡服務。

一:分布式架構網絡通信

在分布式服務框架中,一個最基礎的問題就是遠程服務是怎么通訊的,在Java領域中有很多可實現遠程通訊的技 術,例如:RMI、Hessian、SOAP、ESB和JMS等

1.1:基本原理

要實現網絡機器間的通訊,需要做的就是將流從一臺計算機傳輸到另外一臺計算機,基于傳輸協議和網絡IO來實現。

  • 其中傳輸協議比較出名的有tcp、udp等,tcp、udp都是在基于Socket概念上為某類應用場景而擴展出的傳輸協議。

  • 網絡IO,主要有BIO、NIO、AIO三種方式

1.2:RPC

RPC全稱為remote procedure call,即遠程過程調用。借助RPC可以做到像本地調用一樣調用遠程服務,是一種進程間的通信方式。常見的RPC框架有:Hessian、gRPC、Thrift、HSF、Dubbo等。

注意:需要注意的是RPC并不是一個具體的技術,而是指整個網絡遠程調用過程;對 于RPC框架而言,核心模塊就是通訊序列化。

遠程過程調用分為兩種,現在在服務間通信的方式也基本以這兩種為主:

  • 基于HTTP的restful形式的廣義遠程調用,以spring could的feign和restTemplate為代表,采用的協議是HTTP的7層調用協議,并且協議的參數和響應序列化基本以JSON格式和XML格式為主。

  • 基于TCP的狹義的RPC遠程調用,以阿里的Dubbo為代表,主要通過netty來實現4層網絡協議,NIO來異步傳輸,序列化可以是JSON或者hessian2以及java自帶的序列化等,可以配置。

1.2.1 RPC架構

一個完整的RPC架構里面包含了四個核心的組件,分別是Client,Client Stub,Server以及Server Stub,這個Stub 可以理解為存根。

  • 客戶端(Client),服務的調用方。

  • 客戶端存根(Client Stub),存放服務端的地址消息,再將客戶端的請求參數打包成網絡消息,然后通過網絡遠程發(fā)送給服務方。

  • 服務端(Server),真正的服務提供者。

  • 服務端存根(Server Stub),接收客戶端發(fā)送過來的消息,將消息解包,并調用本地的方法。

Java同步阻塞怎么實現

1.2.2 RPC調用過程

Java同步阻塞怎么實現

注意:無論是何種類型的數據,最終都需要轉換成二進制流在網絡上進行傳輸,數據的發(fā)送方需要將對象轉換為二進制流(序列化),而數據的接收方則需要把二進制流再恢復為對象(反序列化)

1.3:RMI

Java RMI 指的是遠程方法調用 (Remote Method Invocation),是java原生支持的遠程調用 ,采用JRMP(Java Remote Messageing protocol)作為通信協議,可以認為是純java版本的分布式遠程調用解決方案, RMI主要用 于不同虛擬機之間的通信,這些虛擬機可以在不同的主機上、也可以在同一個主機上,因此這里的通信可以理解為一個 虛擬機上的對象調用另一個虛擬機上對象的方法。

1.3.1 RMI簡介

注冊表:
注冊表(Registry):以URL形式注冊遠程對象,并向客戶端回復對遠程對象的引用。

客戶端:

  1. 存根/樁(Stub):遠程對象在客戶端上的代理;

  2. 遠程引用層(Remote Reference Layer):解析并執(zhí)行遠程引用協議;

  3. 傳輸層(Transport):發(fā)送調用、傳遞遠程方法參數、接收遠程方法執(zhí)行結果。

服務端:

  1. 骨架(Skeleton):讀取客戶端傳遞的方法參數,調用服務器方的實際對象方法,并接收方法執(zhí)行后的返回值;

  2. 遠程引用層(Remote Reference Layer):處理遠程引用后向骨架發(fā)送遠程方法調用;

  3. 傳輸層(Transport):監(jiān)聽客戶端的入站連接,接收并轉發(fā)調用到遠程引用層。

1.3.2 RMI調用過程

Java同步阻塞怎么實現

遠程調用過程:
1)客戶端從遠程服務器的注冊表中查詢并獲取遠程對象引用。
2)樁對象與遠程對象具有相同的接口和方法列表,當客戶端調用遠程對象時,實際上是由相應的樁對象代理完成的。
3 ) 遠程引用層在將樁的本地引用轉換為服務器上對象的遠程引用后,再將調用傳遞給傳輸層(Transport),由傳輸層通 過TCP協議發(fā)送調用;
4)在服務器端,傳輸層監(jiān)聽入站連接,它一旦接收到客戶端遠程調用后,就將這個引用轉發(fā)給其上層的遠程引用層;
5)服務器端的遠程引用層將客戶端發(fā)送的遠程應用轉換為本地虛擬機的引用后,再將請求傳遞給骨架(Skeleton);
6)骨架讀取參數,又將請求傳遞給服務器,最后由服務器進行實際的方法調用。

1.4:BIO、NIO、AIO

BIO:同步阻塞的;NIO:同步非阻塞的;AIO:異步非阻塞的。

同步與異步(針對應用程序與內核的交互):

  • 同步:用戶進程觸發(fā)IO操作時,使用等待或者輪訓的方式查看IO操作是否就緒。
    例如:銀行取錢,我自己去取錢,取錢的過程中等待。

  • 異步:當一個異步進程調用發(fā)出之后,調用者不會立刻得到結果。而是在調用發(fā)出之后,被調用者通過狀態(tài)、通知來通知調用者,或者通過回調函數來處理這個調用。
    例如:我請朋友幫我取錢,他取到錢后返回給我.

阻塞與非阻塞(針對進程訪問數據(讀寫操作)的時候,根據IO操作的就緒狀態(tài)采取不同的方式):

  • 阻塞:阻塞方式下讀取和寫入將一直等待
    例: ATM機排隊取款,你只能一直等待排隊取款

  • 非阻塞:使用非阻塞IO時,如果不能讀寫Java調用會馬上返回,當IO事件分發(fā)器會通知可讀寫時再繼續(xù)進行讀寫,不斷循環(huán)直到讀寫完成
    例:柜臺取款,取個號,然后坐在椅子上做其他事,等廣播通知,沒到你的號你就不能去,但你可以不斷的問大堂經理排到了沒有。

1.4.1 BIO(同步阻塞)

BIO:同步阻塞IO,B代表blocking。服務器實現模式為一個連接一個線程,即客戶端有連接請求時服務器端就需要啟動一個線程進行處理,如果這個連接不做任何事情會造成不必要的線程開銷,當然可以通過線程池機制改善。

Java同步阻塞怎么實現

簡單實現:

  1. 服務端代碼

    public static void main(String[] args) throws IOException {
        ServerSocket serverSocket = new ServerSocket();
        serverSocket.bind(new InetSocketAddress("127.0.0.1",8888));
        while (true){
            // 同步阻塞
            Socket socket = serverSocket.accept();
            new Thread(()->{
                try {
                    byte[] bytes = new byte[1024];
                    int len = socket.getInputStream().read(bytes);
                    System.out.println(new String(bytes,0,len));
                    socket.getOutputStream().write(bytes,0,len);
                    socket.getOutputStream().flush();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }).start();
        }
    }
  1. 客戶端代碼

    public static void main(String[] args) throws IOException {
        Socket socket = new Socket("127.0.0.1",8888);
        socket.getOutputStream().write("hello".getBytes());
        socket.getOutputStream().flush();
        System.out.println("server send back data =====");
        byte[] bytes = new byte[1024];
        int len = socket.getInputStream().read(bytes);
        System.out.println(new String(bytes,0,len));
    }

1.4.2 NIO(同步非阻塞)

同步非阻塞IO (non-blocking IO / new io)。服務器實現模式為一個請求對應一個通道(Channel),即客戶端發(fā)送的連接請求都會注冊到多路復用器上,多路復用器輪詢到連接有IO請求時才啟動一個線程進行處理。

  • 通道(Channels):Channel 數據連接的通道。 數據可以從Channel讀到Buffer中,也可以從Buffer 寫到Channel中 .

  • 緩沖區(qū)(Buffers):通道channel可以向緩沖區(qū)Buffer中寫數據,也可以像buffer中存數據。

  • 選擇器(Selector):使用選擇器,借助單一線程,就可對數量龐大的活動 I/O 通道實時監(jiān)控和維護。

Java同步阻塞怎么實現

NIO的特點

Java同步阻塞怎么實現

當一個連接創(chuàng)建后,不會需要對應一個線程,這個連接會被注冊到多路復用器,所有的連接只需要一個線程就可以操作,該線程的多路復用器會輪詢,發(fā)現連接有請求時,才開啟一個線程處理。

Java同步阻塞怎么實現

NIO模型中selector的作用,一條連接來了之后,現在不創(chuàng)建一個while死循環(huán)去監(jiān)聽是否有數據可讀了,而是直接把這條連接注冊到selector上,然后,通過檢查這個selector,就可以批量監(jiān)測出有數據可讀的連接,進而讀取數據,

NIO的使用

nio的使用示例

1.4.3 AIO(異步非阻塞)

異步非阻塞IO。A代表asynchronize

特點:

  • 當有流可以讀時,操作系統會將可以讀的流傳入read方法的緩沖區(qū),并通知應用程序,

  • 對于寫操作,OS將write方法的流寫入完畢時操作系統會主動通知應用程序。因此read和write都是異步 的,完成后會調用回調函數。

Java同步阻塞怎么實現

使用場景: 連接數目多且連接比較長(重操作)的架構,比如相冊服務器。重點調用了OS參與并發(fā)操作,Java7開始支持。

“Java同步阻塞怎么實現”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關的知識可以關注創(chuàng)新互聯網站,小編將為大家輸出更多高質量的實用文章!

網站名稱:Java同步阻塞怎么實現
URL標題:http://bm7419.com/article44/pcgsee.html

成都網站建設公司_創(chuàng)新互聯,為您提供網站設計公司、標簽優(yōu)化、面包屑導航、電子商務、網站維護服務器托管

廣告

聲明:本網站發(fā)布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創(chuàng)新互聯

成都網站建設公司