国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

Java NIO深入理解ServerSocketChannel

masturbator / 3514人閱讀

摘要:組件主要有三大核心部分通道,緩沖區(qū)選擇器。選擇區(qū)用于監(jiān)聽多個(gè)通道的事件比如連接打開,數(shù)據(jù)到達(dá)。即用選擇器,借助單一線程,就可對(duì)數(shù)量龐大的活動(dòng)通道實(shí)施監(jiān)控和維護(hù)。

Java NIO 簡(jiǎn)介
JAVA NIO有兩種解釋:一種叫非阻塞IO(Non-blocking I/O),另一種也叫新的IO(New I/O),其實(shí)是同一個(gè)概念。它是一種同步非阻塞的I/O模型,也是I/O多路復(fù)用的基礎(chǔ),已經(jīng)被越來越多地應(yīng)用到大型應(yīng)用服務(wù)器,成為解決高并發(fā)與大量連接、I/O處理問題的有效方式。

NIO是一種基于通道和緩沖區(qū)的I/O方式,它可以使用Native函數(shù)庫(kù)直接分配堆外內(nèi)存(區(qū)別于JVM的運(yùn)行時(shí)數(shù)據(jù)區(qū)),然后通過一個(gè)存儲(chǔ)在java堆里面的DirectByteBuffer對(duì)象作為這塊內(nèi)存的直接引用進(jìn)行操作。這樣能在一些場(chǎng)景顯著提高性能,因?yàn)楸苊饬嗽贘ava堆和Native堆中來回復(fù)制數(shù)據(jù)。

Java NIO組件
NIO主要有三大核心部分:Channel(通道),Buffer(緩沖區(qū)), Selector(選擇器)。傳統(tǒng)IO是基于字節(jié)流和字符流進(jìn)行操作(基于流),而NIO基于Channel和Buffer(緩沖區(qū))進(jìn)行操作,數(shù)據(jù)總是從通道讀取到緩沖區(qū)中,或者從緩沖區(qū)寫入到通道中。Selector(選擇區(qū))用于監(jiān)聽多個(gè)通道的事件(比如:連接打開,數(shù)據(jù)到達(dá))。因此,單個(gè)線程可以監(jiān)聽多個(gè)數(shù)據(jù)通道。

Buffer
Buffer(緩沖區(qū))是一個(gè)用于存儲(chǔ)特定基本類型數(shù)據(jù)的容器。除了boolean外,其余每種基本類型都有一個(gè)對(duì)應(yīng)的buffer類。Buffer類的子類有ByteBuffer, CharBuffer, DoubleBuffer, FloatBuffer, IntBuffer, LongBuffer, ShortBuffer 。

Channel
Channel(通道)表示到實(shí)體,如硬件設(shè)備、文件、網(wǎng)絡(luò)套接字或可以執(zhí)行一個(gè)或多個(gè)不同 I/O 操作(如讀取或?qū)懭耄┑某绦蚪M件的開放的連接。Channel接口的常用實(shí)現(xiàn)類有FileChannel(對(duì)應(yīng)文件IO)、DatagramChannel(對(duì)應(yīng)UDP)、SocketChannel和ServerSocketChannel(對(duì)應(yīng)TCP的客戶端和服務(wù)器端)。Channel和IO中的Stream(流)是差不多一個(gè)等級(jí)的。只不過Stream是單向的,譬如:InputStream, OutputStream.而Channel是雙向的,既可以用來進(jìn)行讀操作,又可以用來進(jìn)行寫操作。

Selector
Selector(選擇器)用于監(jiān)聽多個(gè)通道的事件(比如:連接打開,數(shù)據(jù)到達(dá))。因此,單個(gè)的線程可以監(jiān)聽多個(gè)數(shù)據(jù)通道。即用選擇器,借助單一線程,就可對(duì)數(shù)量龐大的活動(dòng)I/O通道實(shí)施監(jiān)控和維護(hù)。

Java NIO的簡(jiǎn)單實(shí)現(xiàn)

public class Demo1 {

    private static Integer port = 8080;

    // 通道管理器(Selector)
    private static Selector selector;

    private static ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(1, 10, 1000, TimeUnit.MILLISECONDS, new LinkedTransferQueue<>(), new ThreadPoolExecutor.AbortPolicy());

    public static void main(String[] args) {
        try {
            // 創(chuàng)建通道ServerSocketChannel
            ServerSocketChannel open = ServerSocketChannel.open();

            // 將通道設(shè)置為非阻塞
            open.configureBlocking(false);

            // 綁定到指定的端口上
            open.bind(new InetSocketAddress(port));

            // 通道管理器(Selector)
            selector = Selector.open();

            /**
             * 將通道(Channel)注冊(cè)到通道管理器(Selector),并為該通道注冊(cè)selectionKey.OP_ACCEPT事件
             * 注冊(cè)該事件后,當(dāng)事件到達(dá)的時(shí)候,selector.select()會(huì)返回,
             * 如果事件沒有到達(dá)selector.select()會(huì)一直阻塞。
             */
            open.register(selector, SelectionKey.OP_ACCEPT);

            // 循環(huán)處理
            while (true) {
                /**
                 * 當(dāng)注冊(cè)事件到達(dá)時(shí),方法返回,否則該方法會(huì)一直阻塞
                 * 該Selector的select()方法將會(huì)返回大于0的整數(shù),該整數(shù)值就表示該Selector上有多少個(gè)Channel具有可用的IO操作
                 */
                int select = selector.select();
                System.out.println("當(dāng)前有 " + select + " 個(gè)channel可以操作");

                // 一個(gè)SelectionKey對(duì)應(yīng)一個(gè)就緒的通道
                Set selectionKeys = selector.selectedKeys();
                Iterator iterator = selectionKeys.iterator();
                while (iterator.hasNext()) {
                    // 獲取事件
                    SelectionKey key = iterator.next();

                    // 移除事件,避免重復(fù)處理
                    iterator.remove();

                    // 客戶端請(qǐng)求連接事件,接受客戶端連接就緒
                    if (key.isAcceptable()) {
                        accept(key);
                    } else if (key.isReadable()) {
                        // 監(jiān)聽到讀事件,對(duì)讀事件進(jìn)行處理
                        threadPoolExecutor.submit(new NioServerHandler(key));
                    }
                }

            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 處理客戶端連接成功事件
     *
     * @param key
     */
    public static void accept(SelectionKey key) {
        try {
            // 獲取客戶端連接通道
            ServerSocketChannel ssc = (ServerSocketChannel) key.channel();
            SocketChannel sc = ssc.accept();
            sc.configureBlocking(false);

            // 給通道設(shè)置讀事件,客戶端監(jiān)聽到讀事件后,進(jìn)行讀取操作
            sc.register(selector, SelectionKey.OP_READ);
            System.out.println("accept a client : " + sc.socket().getInetAddress().getHostName());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 監(jiān)聽到讀事件,讀取客戶端發(fā)送過來的消息
     */
    public static class NioServerHandler implements Runnable {

        private SelectionKey selectionKey;

        public NioServerHandler(SelectionKey selectionKey) {
            this.selectionKey = selectionKey;
        }

        @Override
        public void run() {
            try {
                if (selectionKey.isReadable()) {
                    SocketChannel socketChannel = (SocketChannel) selectionKey.channel();

                    // 從通道讀取數(shù)據(jù)到緩沖區(qū)
                    ByteBuffer buffer = ByteBuffer.allocate(1024);

                    // 輸出客戶端發(fā)送過來的消息
                    socketChannel.read(buffer);
                    buffer.flip();
                    System.out.println("收到客戶端" + socketChannel.socket().getInetAddress().getHostName() + "的數(shù)據(jù):" + new String(buffer.array()));

                    //將數(shù)據(jù)添加到key中
                    ByteBuffer outBuffer = ByteBuffer.wrap(buffer.array());

                    // 將消息回送給客戶端
                    socketChannel.write(outBuffer);
                    selectionKey.cancel();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/75111.html

相關(guān)文章

  • Java NIO詳解

    摘要:前言本篇主要講解中的機(jī)制和網(wǎng)絡(luò)通訊中處理高并發(fā)的分為兩塊第一塊講解多線程下的機(jī)制第二塊講解如何在機(jī)制下優(yōu)化資源的浪費(fèi)服務(wù)器單線程下的機(jī)制就不用我介紹了,不懂得可以去查閱下資料那么多線程下,如果進(jìn)行套接字的使用呢我們使用最簡(jiǎn)單的服務(wù)器來幫助大 前言 本篇主要講解Java中的IO機(jī)制和網(wǎng)絡(luò)通訊中處理高并發(fā)的NIO 分為兩塊:第一塊講解多線程下的IO機(jī)制第二塊講解如何在IO機(jī)制下優(yōu)化CPU資...

    rickchen 評(píng)論0 收藏0
  • 基于零拷貝技術(shù)的的java NIO文件下載服務(wù)器

    摘要:什么是零拷貝我們首先來認(rèn)識(shí)一下傳統(tǒng)的操作。因?yàn)樵谶@套體系里,不僅僅提供了非阻塞的編程模型,而且提供了類似零拷貝,內(nèi)存映射這樣的新技術(shù)對(duì)于操作系統(tǒng)來說早就有了。 什么是零拷貝?我們首先來認(rèn)識(shí)一下傳統(tǒng)的I/O操作。假如說用戶進(jìn)程現(xiàn)在要把一個(gè)文件復(fù)制到另一個(gè)地方。那么用戶程序必須先把這個(gè)文件讀入內(nèi)存,然后再把內(nèi)存里的數(shù)據(jù)寫入另一個(gè)文件。不過文件讀入內(nèi)存也不是直接讀入用戶進(jìn)程的內(nèi)存,而是先讀入...

    Keven 評(píng)論0 收藏0
  • java同步非阻塞IO

    摘要:的異步即是異步的,也是非阻塞的。但是,也可以進(jìn)行一層稍微薄點(diǎn)的封裝,保留這種多路復(fù)用的模型,比如的,是一種同步非阻塞的模型。系統(tǒng)調(diào)用操作系統(tǒng)的系統(tǒng)調(diào)用提供了多路復(fù)用的非阻塞的系統(tǒng)調(diào)用,這也是機(jī)制實(shí)現(xiàn)需要用到的。 異步IO編程在javascript中得到了廣泛的應(yīng)用,之前也寫過一篇博文進(jìn)行梳理。js的異步IO即是異步的,也是非阻塞的。非阻塞的IO需要底層操作系統(tǒng)的支持,比如在linux上...

    caoym 評(píng)論0 收藏0
  • Netty4.x 源碼實(shí)戰(zhàn)系列(一):ServerBootstrap 與 Bootstrap 初探

    摘要:而用于主線程池的屬性都定義在中本篇只是簡(jiǎn)單介紹了一下引導(dǎo)類的配置屬性,下一篇我將詳細(xì)介紹服務(wù)端引導(dǎo)類的過程分析。 從Java1.4開始, Java引入了non-blocking IO,簡(jiǎn)稱NIO。NIO與傳統(tǒng)socket最大的不同就是引入了Channel和多路復(fù)用selector的概念。傳統(tǒng)的socket是基于stream的,它是單向的,有InputStream表示read和Outpu...

    BakerJ 評(píng)論0 收藏0
  • Java NIO 之 Channel(通道)

    摘要:通道可以異步讀寫。使用的方法讀取數(shù)據(jù)創(chuàng)建一個(gè)讀數(shù)據(jù)緩沖區(qū)對(duì)象從通道中讀取數(shù)據(jù)使用的方法寫入數(shù)據(jù)創(chuàng)建一個(gè)寫數(shù)據(jù)緩沖區(qū)對(duì)象寫入數(shù)據(jù)關(guān)閉完成使用后,您必須關(guān)閉它。五提供了一種被稱為的新功能,也稱為本地矢量。功能是通道提供的并不是。 歷史回顧: Java NIO 概覽 Java NIO 之 Buffer(緩沖區(qū)) 其他高贊文章: 面試中關(guān)于Redis的問題看這篇就夠了 一文輕松搞懂redis集...

    piglei 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<