1. 程式人生 > >Java NIO 選擇器(Selector)的內部實現(poll epoll)

Java NIO 選擇器(Selector)的內部實現(poll epoll)

之前強調這麼多關於linux核心的poll及epoll,無非是想讓大家先有個認識:


Java NIO中的選擇器依賴作業系統核心的這些系統呼叫,我們這裡只講解與linux核心相關的NIO實現,當然,windows或其他作業系統實現大體上是類似的,相信大家也可以觸類旁通。


那麼,本文從這裡將從簡到難,一步一步為大家講解選擇器的點點滴滴吧。


選擇器的巨集觀理解
“有這麼一種檢查員,她工作在養雞場,每天的工作就是不停的檢視特定的雞舍,如果有雞生蛋了,或者需要餵食,或者有雞生病了,就把相應資訊記錄下來,這樣一來,雞舍負責人想知道雞舍的情況,只需要到檢查員那裡查詢即可,當然,雞舍負責人得事先告知檢查員去查詢哪些雞舍。“


以上這段話即為選擇器所做工作的一個比喻,實際上選擇器為通道服務,通道事先告訴選擇器:“我對某些事件感興趣,如可讀、可寫等“,選擇器在接受了一個或多個通道的委託後,開始選擇工作,它的選擇工作就完全交給作業系統,linux下即為poll或epoll。


選擇器的建立
當呼叫Selector.open()時,選擇器通過專門的工廠SelectorProvider來建立Selector的實現,SelectorProvider遮蔽了不同作業系統及版本建立實現的差異性。具體實現程式碼如下:


java.nio.channels.Selector




public static Selector open() throws IOException {
    return SelectorProvider.provider().openSelector();
}
因為SelectorProvider本身為一個抽象類,通過呼叫provider()提供對應的Provider實現,如PollSelectorProvider、EPollSelectorProvider


java.nio.channels.spi.SelectorProvider


public static SelectorProvider provider() {
synchronized (lock) {
    if (provider != null)
    return provider;
    return (SelectorProvider)AccessController
    .doPrivileged(new PrivilegedAction() {
        public Object run() {
            if (loadProviderFromProperty())
            return provider;
            if (loadProviderAsService())
            return provider;
            provider = sun.nio.ch.DefaultSelectorProvider.create();
            return provider;
        }
        });
}
}
預設的Provider實現即為DefaultSelectorProvider,通過呼叫create(),得到具體的SelectorProvider


sun.nio.ch.DefaultSelectorProvider




public static SelectorProvider create() {
PrivilegedAction pa = new GetPropertyAction("os.name");
String osname = (String) AccessController.doPrivileged(pa);
    if ("SunOS".equals(osname)) {
        return new sun.nio.ch.DevPollSelectorProvider();
    }
 
    // use EPollSelectorProvider for Linux kernels >= 2.6
    if ("Linux".equals(osname)) {
        pa = new GetPropertyAction("os.version");
        String osversion = (String) AccessController.doPrivileged(pa);
        String[] vers = osversion.split("\\.", 0);
        if (vers.length >= 2) {
            try {
                int major = Integer.parseInt(vers[0]);
                int minor = Integer.parseInt(vers[1]);
                if (major > 2 || (major == 2 && minor >= 6)) {
                    return new sun.nio.ch.EPollSelectorProvider();
                }
            } catch (NumberFormatException x) {
                // format not recognized
            }
        }
    }
 
    return new sun.nio.ch.PollSelectorProvider();
}
這是linux作業系統下的DefaultSelectorProvider的實現,可以看到,如果核心版本>=2.6則,具體的SelectorProvider為EPollSelectorProvider,否則為預設的PollSelectorProvider


結合上文,可以猜測一下EPollSelectorProvider提供的Selector肯定是與核心epoll有關的,PollSelectorProvider提供的
Selector肯定是與poll有關的。的確如此:


sun.nio.ch.EPollSelectorProvider




public AbstractSelector openSelector() throws IOException {
    return new EPollSelectorImpl(this);
}
sun.nio.ch.PollSelectorProvider


public AbstractSelector openSelector() throws IOException {
    return new PollSelectorImpl(this);
}

相關推薦

Java NIO 選擇(Selector)的內部實現poll epoll

之前強調這麼多關於linux核心的poll及epoll,無非是想讓大家先有個認識: Java NIO中的選擇器依賴作業系統核心的這些系統呼叫,我們這裡只講解與linux核心相關的NIO實現,當然,windows或其他作業系統實現大體上是類似的,相信大家也可以觸類旁通。 那

Java Nio選擇Selector

Selector(選擇器)是Java NIO中能夠檢測一到多個NIO通道,並能夠知曉通道是否為諸如讀寫事件做好準備的元件。這樣,一個單獨的執行緒可以管理多個channel,從而管理多個網路連線 ,減少伺服器的效能開銷。 建立Selector 通過Selector 提供的

Java NIO 選擇 Selector

選擇器 Selector 是 I/O 多路複用的核心元件,它可以監控實現了 SelectableChannel 的[通道](https://www.cnblogs.com/robothy/p/14234437.html)的就緒情況。有了多路複用(multiplexing) I/O 模型,使得單執行緒的 Jav

NIO 選擇 Selector

字節 () 激發 就是 異常檢查 執行 1.4 移植 異常   選擇器提供選擇執行已經就緒的任務的能力,這使得多元 I/O 成為可能。就像在第一章中描述的那樣,就緒選擇和多元執行使得單線程能夠有效率地同時管理多個 I/O 通道(Channels)。C/C++代碼的工具箱中,

Java NIO類庫Selector機制解析

在使用Java進行相關網路程式的的設計時,出身C/C++的人,首先想到的框架就是多路複用,想到多路複用,Unix/Linux下馬上就能讓從想到select, poll, epoll系統呼叫。於是,在看到Java的NIO中的Selector類時必然會倍感親切。稍加查閱一下SDK手冊以及相關例程,不一會兒,一個多

[Java併發程式設計實戰] 柵欄 CyclicBarrier 實現含程式碼

溫故而知新,可以為師矣。—《論語》 它的意思是:“溫習舊知識從而得知新的理解與體會,憑藉這一點就可以成為老師了 PS: 如果覺得本文有用的話,請幫忙點贊,留言評論支援一下哦,您的支援是我最大的動力!謝謝啦~ 柵欄(Barrier)類似於閉鎖,

android中listview的item點選切換實現效果選擇selector

public class V2_Adapter_TarentoCreateActivity_OverSea_City extends BaseAdapter{private V2_TarentoCreateActivity_OverSea_Place v2_TarentoCreateActivity_Over

Java NIO通俗程式設計之選擇Selector(四)

最後一步就是根據不同的事件,編寫相應的處理程式碼:/* * 根據不同的事件做處理 * */ protected void process(SelectionKey key) throws IOException{ // 接收請求 if (key.isAcceptable()) {

java nio--采用Selector實現Socket通信

lock finish taf 取數 block static isempty inpu col server: 1 /** 2 * 選擇器服務端 3 * Created by ascend on 2017/6/9 9:30. 4 */ 5 pu

Java學習總結二十四——前端:CSS樣式設計CSS引入,選擇,盒子模型,浮動元素

引入 itl AI dropdown 正常的 type ID 總結 網頁 一.CSS引入方式1.CSS簡介:(1)CSS(Cascading style Sheets):層疊樣式表。用來給html網頁設置樣式;(2)當多個選擇器對同一個元素進行樣式設計時,則該元素的樣式為多

簡單選擇排序演算法原理及java實現超詳細

選擇排序是一種非常簡單的排序演算法,就是在序列中依次選擇最大(或者最小)的數,並將其放到待排序的數列的起始位置。 簡單選擇排序的原理 簡單選擇排序的原理非常簡單,即在待排序的數列中尋找最大(或者最小)的一個數,與第 1 個元素進行交換,接著在剩餘的待排序的數列中繼續找最大(最小)的一個數,與第 2 個元素交

JAVA jsoup 爬蟲 傻瓜入門實錄 (2-1) 選擇 Selector 實務分解說明

JAVA jsoup 爬蟲 傻瓜入門實錄 (2-1) 選擇器 Selector 實務分解說明這部分要講解的是個人常用的jsoup選擇器說明上一篇我們講完各種型態解析成Document型態的方法實做當我們解析成Document後 就可以開始做爬蟲的動作爬蟲前我們應該先分析要抓取的網頁資料你要抓的資料是在哪個di

java 日期選擇帶時間

import java.awt.BorderLayout; import java.awt.Color; import java.awt.Cursor; import java.awt.Dimension; import java.awt.FlowLayo

使用xpath實現document.querySelector樣式選擇進行html解析:將選擇結果封裝進行輸出

-----------------------------------------------------------------恩,其實到目前為止,關於xpath解析html的樣式選擇器其實已經完工了,而且,應該說比預期的目的還多出了一丟丟的效果例如:QuerySelect

NIO中和選擇Selector

NIO中和選擇器Selector 在上一篇的JAVA中NIO再深入我們學會了如何使用Buffer,而在Java中IO和NIO中我們

jQuery選擇絕對定位實現div覆蓋

rip jquer 絕對定位 button min 覆蓋 str fun 選擇 新建html文件可以運行(jsp文件下不可運行) <!DOCTYPE html><html> <head> <meta charse

手機影音第六天 自定義播放頁面的實現按鈕暫時未監聽

手機影音第六天 自定義播放器布局以及橫豎屏切換播放器時的問題解決 目前進度的項目源代碼托管在裏碼雲上,地址如下: https://git.oschina.net/joy_yuan/MobilePlayer 感興趣的可以去下載看看,多多支持

Java Integer 進制轉化的實現附源碼,對模與補碼的理解

api style fse 計算 log 一律 mas 使用 對比 1.toBinaryString方法的實現 1 public static String toBinaryString(int i) { 2 return toUnsignedString0(i, 1

HTML學習筆記 CSS學習選擇 第五節 原創

ext spa family 如果 styles ctype css gre utf <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <

基於Java的大整數運算的實現加法,減法,乘法學習筆記

-1 urn 相加 his add oid one 我會 後來 大整數,顧名思義就是特別大的整數。 一臺64位的機器最大能表示的數字是2的64次方減一: 18446744073709551615 java語言中所能表示的整數(int)最小為-2147483648 pu