導航:首頁 > 編程語言 > reactorjava

reactorjava

發布時間:2022-07-25 08:59:10

① 求教:java多線程與響應式流

② java里的nio和concurrent是在什麼時候使用的

NIO是網路編程里的reactor模式,一般用了NIO就很難用到concurrent,做網站用不到。concurrent在多線程的時候會用到。

③ java網路io模型有幾種

#BIO---Blocking IO
- 每個socket一個線程,讀寫時線程處於阻塞狀態。
優點:實現簡單
缺點:無法滿足高並發,高接入的需求

- 不使用線程池的BIO模型,除了無法滿足高並發需求外,由於需要為每個請求創建一個線程,還可能因為接入大量不活躍連接而耗盡伺服器資源。

- 使用線程池的BIO模型,雖然控制了線程數量,但由於其本質上讀寫仍是阻塞的,仍無法滿足高並發需求。

#NIO---Non-Blocking IO(非阻塞IO)
##非阻塞IO和多路復用
非阻塞IO和多路復用實際上是兩個不用的概念,由於兩者通常結合在一起使用,因此兩者往往被混為一談。下面我將試著分清這兩個概念:
###非阻塞IO
與BIO相對應,非阻塞IO的讀寫方法無論是否有數據都立即返回,因此可以通過輪詢方式來實現,但輪詢方式的效率並不比BIO有顯著提高,因為每個連接仍然需要佔用一個線程。下面是輪詢方式實現的IO模式圖:

###多路復用
- 多路復用結合非阻塞IO能夠明顯提高IO的效率,這也是Java1.4把非阻塞IO和多路復用同時發布的原因。
- 多路復用的核心是多路復用器(Selector),它是需要操作系統底層支持的,簡單的說,就是進程把多個socket和它們關心的事件(比如連接請求或數據已准備好)都注冊在多路復用器上,操作系統會在事件發生時通知多路復用器,這樣進程就可以通過多路復用器知道在那個socket上發生了什麼時間,從而進行對應的處理。
- 多路復用的優點在於只需要一個線程監測(阻塞或輪詢方式均可)多路選擇器的狀態,只有在有事件需要發生時才會真正的創建線程進行處理,因此更適合高並發多接入的應用環境。

- 在linux系統下,多路復用的底層實現是epoll方法,與select/poll的順序掃描不同,epoll採用效率更高的事件驅動方式,而且epoll方式並沒有socket個數限制。
##BIO和NIO的比較
- BIO適用於連接長期保持的應用,比如一個復雜系統中模塊之間通過長連接來進行通信。
- NIO加多路復用的模式更適合短連接、高並發、多接入的情形,比如網路伺服器。
##NIO網路編程的常用介面
##Reactor模式
Reactor模式用於解決事件分發處理的問題,Handler把自己的channel和關注的事件注冊到Selector中,當對應的事件發生在自己的channel上時,對應的handler就會得到通知並進行處理。
- 單線程的Reactor
消息的分發、讀寫、處理都在一個線程中處理,是Reactor最簡單的實現方式,如果消息的處理需要較長時間,會影響效率。

```java

//Reactor類,負責分發事件並調用對應的handler
class Reactor implements Runnable {

final Selector selector;

final ServerSocketChannel serverSocket;

//Reactor初始化

Reactor(int port) throws IOException {

selector = Selector.open();

serverSocket = ServerSocketChannel.open();

serverSocket.socket().bind(new InetSocketAddress(port));

serverSocket.configureBlocking(false); //必須配置為非阻塞

//Acceptor會在Reactor初始化時就注冊到Selector中,用於接受connect請求
SelectionKey sk = serverSocket.register(selector, SelectionKey.OP_ACCEPT);

sk.attach(new Acceptor()); //attach callback object, Acceptor

}

//分發消息並調用對應的handler
public void run() {
try {

while (!Thread.interrupted()) {

selector.select();

Set selected = selector.selectedKeys();

Iterator it = selected.iterator();

while (it.hasNext())

dispatch((SelectionKey)(it.next()); //Reactor負責dispatch收到的事件

selected.clear();

}

} catch (IOException ex) { /* ... */ }

}

void dispatch(SelectionKey k) {

Runnable r = (Runnable)(k.attachment()); //調用之前注冊的callback對象

if (r != null)

r.run();

}

//Acceptor也是一個handler,負責創建socket並把新建的socket也注冊到selector中

class Acceptor implements Runnable { // inner

public void run() {

try {

SocketChannel c = serverSocket.accept();

if (c != null)

new Handler(selector, c);

}

catch(IOException ex) { /* ... */ }

}

}

}

//Concrete Handler:用於收發和處理消息。
//在當前的實現中,使用Runnable介面作為每個具體Handler的統一介面
//如果在處理時需要參數和返回值,也可以為Handler另外聲明一個統一介面來代替Runnable介面
final class Handler implements Runnable {

final SocketChannel socket;

final SelectionKey sk;

ByteBuffer input = ByteBuffer.allocate(MAXIN);

ByteBuffer output = ByteBuffer.allocate(MAXOUT);

static final int READING = 0, SENDING = 1;

int state = READING;

Handler(Selector sel, SocketChannel c) throws IOException {

socket = c; c.configureBlocking(false);

// Optionally try first read now

sk = socket.register(sel, 0);

sk.attach(this); //將Handler作為callback對象

sk.interestOps(SelectionKey.OP_READ); //第二步,接收Read事件

sel.wakeup();

}

boolean inputIsComplete() { /* ... */ }

boolean outputIsComplete() { /* ... */ }

void process() { /* ... */ }

public void run() {

try {

if (state == READING) read();

else if (state == SENDING) send();

} catch (IOException ex) { /* ... */ }

}

void read() throws IOException {

socket.read(input);

if (inputIsComplete()) {

process();

state = SENDING;

// Normally also do first write now

sk.interestOps(SelectionKey.OP_WRITE); //第三步,接收write事件

}

}

void send() throws IOException {

socket.write(output);

if (outputIsComplete()) sk.cancel(); //write完就結束了, 關閉select key

}

}

//上面 的實現用Handler來同時處理Read和Write事件, 所以裡面出現狀態判斷

//我們可以用State-Object pattern來更優雅的實現

class Handler { // ...

public void run() { // initial state is reader

socket.read(input);

if (inputIsComplete()) {

process();

sk.attach(new Sender()); //狀態遷移, Read後變成write, 用Sender作為新的callback對象

sk.interest(SelectionKey.OP_WRITE);

sk.selector().wakeup();

}

}

class Sender implements Runnable {

public void run(){ // ...

socket.write(output);

if (outputIsComplete()) sk.cancel();

}

}

}

```
- 多線程Reacotr
處理消息過程放在其他線程中執行

```java
class Handler implements Runnable {

// uses util.concurrent thread pool

static PooledExecutor pool = new PooledExecutor(...);

static final int PROCESSING = 3;

// ...

synchronized void read() { // ...

socket.read(input);

if (inputIsComplete()) {

state = PROCESSING;

pool.execute(new Processer()); //使用線程pool非同步執行

}

}

synchronized void processAndHandOff() {

process();

state = SENDING; // or rebind attachment

sk.interest(SelectionKey.OP_WRITE); //process完,開始等待write事件

}

class Processer implements Runnable {

public void run() { processAndHandOff(); }

}

}

```
- 使用多個selector
mainReactor只負責處理accept並創建socket,多個subReactor負責處理讀寫請求

```java
Selector[] selectors; //subReactors集合, 一個selector代表一個subReactor

int next = 0;

class Acceptor { // ...

public synchronized void run() { ...

Socket connection = serverSocket.accept(); //主selector負責accept

if (connection != null)

new Handler(selectors[next], connection); //選個subReactor去負責接收到的connection

if (++next == selectors.length) next = 0;

}

}

```
#AIO
AIO是真正的非同步IO,它於JDK1.7時引入,它和NIO的區別在於:
- NIO仍然需要一個線程阻塞在select方法上,AIO則不需要
- NIO得到數據准備好的消息以後,仍然需要自己把消息復制到用戶空間,AIO則是通過操作系統的支持把數據非同步復制到用戶空間以後再給應用進程發出信號。

④ 求助,誰能看懂混淆的反編譯後混淆的Java代碼

reactor主界面上就有幾個復選框,試一下全部打勾,然後點proctect,混淆後的Dll再用反編譯軟體看看其中的代碼,lz自然會知道結果。

⑤ xmemcached-reactor 是什麼線程

.code.yanf4j.nio.impl.Reactor.checkSessionTimeout(Reactor.java:364)
at com.google.code.yanf4j.nio.impl.Reactor.run(Reactor.java:121)
Exception in thread 「Xmemcached-Reactor-2」 java.lang.NullPointerException
at org.slf4j.impl.Log4jLoggerAdapter.error(Log4jLoggerAdapter.java:485)
at net.rubyeye.xmemcached.impl.MemcachedHandler.onExceptionCaught

⑥ 如何看待Spring 5引入函數式編程思想以及Reactor

讀源代碼 至少幾萬行那種 讀上個一個月,讀到覺得自己以後再也不怕讀代碼了 2. 寫程序,可以從頭寫,或是修改大的程序 寫到你覺得想做什麼就寫的出什麼的地步(即便這只是自己的錯覺)

⑦ Java多線程 Reactor模式和NIO

java nio從1.4版本就出現了,而且依它優異的性能贏得了廣大java開發愛好者的信賴。我很納悶,為啥我到現在才接觸,難道我不是愛好者,難道nio不優秀。經過長達半分鍾的思考,我意識到:時候未到。以前總是寫那些老掉牙的web程序,唉,好不容易翻身啦,現在心裡好受多了。因為真不想自己到了30歲,還在說,我會ssh,會ssi,精通javascript,精通資料庫,精通。。。人生苦短,要開拓點不是嗎?列為兄弟姐妹,沒看到外國的和尚已經開始鼓吹「雲里霧里」的?沒看到網路進入「框」啦,沒看到oracle的「格」啦。人家的經,隨他念,但是我們的確有好多路要走哦(牢騷怎麼這么多呀)。
現在終於到了我了解nio的時候了,突然發現有很多美妙程序的源碼,不得不爽一把(有邪念者,該打住啦,像我這樣)。
以下描述,為了說明問題,就提提歷史(類似的東西,網上一搜一大把,但是希望你能在這里止步,知道到底是怎麼回事。如果還是不清楚,咱就站內溝通!)。
在我(剛)看nio的這段時間里,主要接觸了幾個東西,就是關於server和client。java之前的io完全可以勝任,但是效率不高,為何效率不高呢?
===============history==start===============
//TODO:finish the old style of server and socket data transion.
ServerSocket socket = new ServerSocket(80);
while (true) {
final Socket connection = socket.accept();
handleRequest(connection);
}
===============history==end in the future================
在上面的代碼片段中,我們只能是一個request一個的進行處理。這使得所有的請求都阻塞了。如果我們再改變一下,將handleRequest方法封裝到線程中處理:
if(connection = null){
new Thread(new Runnable(){
public void run(){
handleRequest(connection);
}
public void handleRequest(Socket conn){
//do actions
}
}).start();
}
伺服器端的資源是有限的,我們這里僅僅是從線程角度來擴展,但是這種處理依然是阻塞的處理方式。首先,僅僅是建立連接(socket),就佔用了伺服器的線程資源。如果客戶端還沒有發出相應的數據請求,那麼伺服器就要一直等待他們的數據流過來,然後再進行讀取,如此往復。。。一直都blocking。伺服器處在一個高負荷狀態中。
NIO出來之後,進入改革開放時期,有了這么幾個角色,ServerSocketChannel,SelectionKey,Selector.
這幾個角色都是做什麼用的呢?需要了解一下reactor模式(反應堆模式)。
作為服務端,如果什麼操作都要依賴於客戶端,很多操作都阻塞,如上面的代碼片段所示

⑧ linux下的reactor和epoll的區別

基本的IO編程過程(包括網路IO和文件IO)是,打開文件描述符(windows是handler,Java是stream或channel),多路捕獲(Multiplexe,即select和poll和epoll)IO可讀寫的狀態,而後可以讀寫的文件描述符進行IO讀寫,由於IO設備速度和CPU內存比速度

閱讀全文

與reactorjava相關的資料

熱點內容
dota2怎麼設置國服伺服器地址 瀏覽:212
單片機高電平驅動 瀏覽:115
ios多選文件夾 瀏覽:909
加強行車調度命令管理 瀏覽:243
伺服器已禁用什麼意思 瀏覽:150
部隊命令回復 瀏覽:755
神奇寶貝伺服器地圖怎麼設置 瀏覽:382
加密演算法輸出固定長度 瀏覽:862
程序員去重慶還是武漢 瀏覽:121
伺服器如何撤銷網頁登錄限制 瀏覽:980
微信公眾平台php開發視頻教程 瀏覽:628
怎麼看蘋果授權綁定的app 瀏覽:255
壓縮機單級壓縮比 瀏覽:380
linux測試php 瀏覽:971
什麼時候梁旁邊需要加密箍筋 瀏覽:40
微信清粉軟體源碼 瀏覽:717
matlabdoc命令 瀏覽:550
如何去ping伺服器 瀏覽:75
ecshop安裝php55 瀏覽:817
javaword庫 瀏覽:958