亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Java筆記之從IO模型到Netty框架學習初識篇

 更新時間:2022年03月18日 14:43:09   作者:明天一定.  
Netty作為一個已經發(fā)展了十多年的框架,已然非常成熟了,其中有大量的細節(jié)是普通使用者不知道或者不關心的,本文帶你查缺補漏掌握Netty的使用

什么是Netty

  • 異步,基于事件驅動的網絡應用框架,用以快速開發(fā)高性能,高可靠的網絡IO程序
  • 主要針對在TCP協(xié)議下,面向Clients端的高并發(fā)應用
  • 本質是一個NIO框架,適用于服務器通訊等場景

異步:發(fā)送請求無需等待響應,程式接著往下走。

事件驅動:一個連接事件或者斷開事件,或者讀事件或者寫事件,發(fā)生后的后續(xù)處理。

Netty典型應用:

  • 高性能rpc框架用來遠程服務(過程)調用,比如Dubbo。
  • 游戲行業(yè),頁面數據交互。
  • 大數據領域如Hadoop高性能通訊和序列化組件(AVRO)。

IO模型

簡單理解就是用什么通道去進行數據發(fā)送和接收。

BIO:一個連接一個線程,連接不做任何事會造成不必要的線程開銷。適用于連接數目較小且固定的架構。

NIO:服務端一個線程(也可以多個),維護一個多路復用器。由多路復用器去處理IO線程。適用于連接數目多且較短的架構

AIO:異步非阻塞,還未得到廣泛應用。適用于連接數目多且連接較長的架構。

BIO

BIO編程簡單流程

  • 服務端創(chuàng)建啟動ServerSocket
  • 客戶端啟動Socket對服務器進行通信,默認服務器會對每一個客戶創(chuàng)建一個線程。
  • 客戶端發(fā)出請求后,先咨詢線程是否有響應,如果沒有則等待或者拒絕。
  • 如果有響應,則等待請求結束后,再繼續(xù)執(zhí)行。(阻塞)

BIO簡單實例

public class BIOserver {
    public static void main(String[] args) throws IOException {
        // 為了方便直接用了Executors創(chuàng)建線程池
        ExecutorService service = Executors.newCachedThreadPool();
        //指定服務端端口
        ServerSocket serverSocket = new ServerSocket(6666);
        System.out.println("服務器啟動");
        while(true){
            //阻塞等待連接
            Socket socket = serverSocket.accept();
            System.out.println("連接到一個客戶端");
            //每個連接對應一個線程
            service.execute(new Runnable() {
                @Override
                public void run() {
                    try {
                        handler(socket);
                    }catch (Exception e){
                        e.printStackTrace();
                    }
                }
            });
        }
    }
    public static void handler(Socket socket) throws IOException {
        System.out.println("Thread:"+Thread.currentThread().getId());
        byte[] bytes = new byte[1024];
        InputStream inputStream = socket.getInputStream();
        while (true){
            //阻塞等待讀取
            int n = inputStream.read(bytes);
            if(n!=-1){
                System.out.println(new String(bytes,0,n));
            }else {
                break;
            }
        }
        socket.close();
    }
}

測試:使用windows的telnet

使用 ctrl+]

?可以在服務端控制臺看到,已經讀取到發(fā)送的數據

NIO

三大核心部分:Channel(可類比Socket),Buffer,Selector

大概是這個樣子??蛻舳撕虰uffer交互,Buffer和Channel是一對一的關系。Selector選擇操作Channel(事件驅動,如果Channel有事件發(fā)生,Selector才去選擇操作。)

Buffer

Buffer基本使用

ByteBuffer使用場景較為廣泛。

buffer就是一個內存塊,所以說nio是面向塊/緩沖,底層是數組。數據讀寫是通過buffer??梢允褂梅椒╢lip切換讀寫。

public class BufferNio {
    public static void main(String[] args) {
        //創(chuàng)建buffer容量為5個int
        IntBuffer buffer = IntBuffer.allocate(5);
        //放數據
        buffer.put(1);
        buffer.put(2);
        buffer.put(3);
        buffer.put(4);
        buffer.put(5);
        //讀寫切換
        buffer.flip();
        //取數據
        //內部維護一個索引,每次get索引都會往后邊移動
        while(buffer.hasRemaining()){
            System.out.println(buffer.get());
        }
    }
}

Buffer四個主要屬性

    // Invariants: mark <= position <= limit <= capacity
    private int mark = -1;
    private int position = 0;
    private int limit;
    private int capacity;

mark:標記,很少改變

position:下一個要被讀元素的位置,為下次讀寫做準備

limit:緩沖器當前的終點,不能對緩沖區(qū)極限意外的區(qū)域讀寫,可變。

capacity:不可變,創(chuàng)建時指定的最大容量。

上邊出現了讀寫切換的方法flip,我們看下源碼,可以看出來通過改變屬性實現可讀可寫的。

    public final Buffer flip() {
        limit = position;
        position = 0;
        mark = -1;
        return this;
    }

可以通過啊更改limit或者position來實現你想要的操作。參數自己決定

        buffer.limit(2);
        buffer.position(1);

Channel

可讀可寫,上接Selector,下連Buffer。

當客戶端連接ServerSocketChannel時,創(chuàng)建客戶端自己的SocketChannel。

本地文件寫案例

public class ChannelNio {
    public static void main(String[] args) throws IOException {
        String str = "少壯不努力,老大徒傷悲";
        //創(chuàng)建輸出流
        FileOutputStream os = new FileOutputStream("D:\\xxxxxxxxxxxxxxxxxxx\\a.txt");
        //獲取FileChannel
        FileChannel channel = os.getChannel();
        //創(chuàng)建緩沖
        ByteBuffer buffer = ByteBuffer.allocate(1024);
        //把字符串放入緩沖區(qū)
        buffer.put(str.getBytes());
        //反轉ByteBuffer
        buffer.flip();
        //將ByteBuffer寫入到FileChannel
        channel.write(buffer);
        //關閉流
        os.close();
    }
}

圖示理解

本地文件讀案例

public class ChannelNio {
    public static void main(String[] args) throws IOException {
        FileInputStream is = new FileInputStream("D:\\xxxxxxxxxxxxxxxxxxx\\a.txt");
        FileChannel channel = is.getChannel();
        ByteBuffer buffer = ByteBuffer.allocate(1024);
        channel.read(buffer);
        System.out.println(new String(buffer.array()));
        is.close();
    }
}

本地文件拷貝案例

方法一

public class ChannelNio {
    public static void main(String[] args) throws IOException {
        FileInputStream is = new FileInputStream("D:\\xxxxxxxxxxxxxxxxxxx\\a.txt");
        FileChannel channel = is.getChannel();
        ByteBuffer buffer = ByteBuffer.allocate(1024);
        FileOutputStream os = new FileOutputStream("D:\\xxxxxxxxxxxxxxxxxxx\\b.txt");
        FileChannel osChannel = os.getChannel();
        while (true){
            buffer.clear();
            int i = channel.read(buffer);
            if(i==-1){
                break;
            }
            buffer.flip();
            osChannel.write(buffer);
        }
        is.close();
        os.close();
    }
}

方法二

public class ChannelNio {
    public static void main(String[] args) throws IOException {
        FileInputStream is = new FileInputStream("D:\\xxxxxxxxxxxxxxxxxxx\\HELP.md");
        FileChannel channel = is.getChannel();
        FileOutputStream os = new FileOutputStream("D:\\xxxxxxxxxxxxxxxxxxx\\HELP222.md");
        FileChannel osChannel = os.getChannel();
        osChannel.transferFrom(channel,0,channel.size());
        is.close();
        os.close();
    }
}

Selector

用一個線程處理多個客戶端連接。可以檢測多個注冊通道的事件,并作出相應處理。不用維護所有線程。

Selector可以獲得被注冊的SocketChannel的一個SelectionKey集合,然后監(jiān)聽select,獲得有事件發(fā)生的SelectionKey,最后通過SelectionKey獲得通道進行相應操作,完成業(yè)務。

到此這篇關于Java筆記之從IO模型到Netty框架學習初識篇的文章就介紹到這了,更多相關Java Netty框架內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • 詳解多線程及Runable 和Thread的區(qū)別

    詳解多線程及Runable 和Thread的區(qū)別

    這篇文章主要介紹了多線程及Runable 和Thread的區(qū)別,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-04-04
  • java中線程安全的list詳細特性和用法

    java中線程安全的list詳細特性和用法

    這篇文章主要給大家介紹了關于java中線程安全的list詳細特性和用法的相關資料,Java中有多種線程安全的List,其中比較常用的有Vector、Collections.synchronizedList()和CopyOnWriteArrayList三種方式,需要的朋友可以參考下
    2024-03-03
  • java多線程編程技術詳解和實例代碼

    java多線程編程技術詳解和實例代碼

    這篇文章主要介紹了 java多線程編程技術詳解和實例代碼的相關資料,需要的朋友可以參考下
    2017-04-04
  • spring中的BeanFactory與FactoryBean的講解

    spring中的BeanFactory與FactoryBean的講解

    今天小編就為大家分享一篇關于spring中的BeanFactory與FactoryBean的講解,小編覺得內容挺不錯的,現在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2019-01-01
  • Java異步編程之Callbacks與Futures模型詳解

    Java異步編程之Callbacks與Futures模型詳解

    這篇文章主要為大家詳細介紹了Java異步編程中Callbacks與Futures模型的使用,文中的示例代碼講解詳細,感興趣的小伙伴可以跟隨小編一起學習一下
    2023-03-03
  • Java中數組的定義與使用詳解

    Java中數組的定義與使用詳解

    這篇文章主要給大家介紹了關于Java中數組的定義與使用的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2021-11-11
  • 解決Java項目啟動報錯:Logback?configuration?error?detected:問題

    解決Java項目啟動報錯:Logback?configuration?error?detected:問題

    這篇文章主要介紹了解決Java項目啟動報錯:Logback?configuration?error?detected:問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-04-04
  • 使用SkyWalking監(jiān)控Java服務的過程

    使用SkyWalking監(jiān)控Java服務的過程

    這篇文章主要介紹了使用SkyWalking監(jiān)控Java服務,介紹一個對源碼0入侵的Java服務監(jiān)控方式,SkyWalking Agent,只需要啟動Java程序的時候加幾個參數,就能對Java服務進行可視化監(jiān)控,需要的朋友可以參考下
    2023-08-08
  • Spring的Aware接口實現及執(zhí)行順序詳解

    Spring的Aware接口實現及執(zhí)行順序詳解

    這篇文章主要為大家介紹了Spring的Aware接口實現及執(zhí)行順序詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-12-12
  • springboot多數據源配置及切換的示例代碼詳解

    springboot多數據源配置及切換的示例代碼詳解

    這篇文章主要介紹了springboot多數據源配置及切換,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-09-09

最新評論