欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費電子書(shū)等14項超值服

開(kāi)通VIP
Java多線(xiàn)程 Reactor模式和NIO

Reactor模式和NIO

板橋里人 jdon.com 2002/11/08

本文可看成是對Doug Lea Scalable IO in Java一文的翻譯。

當前分布式計算 Web Services盛行天下,這些網(wǎng)絡(luò )服務(wù)的底層都離不開(kāi)對socket的操作。他們都有一個(gè)共同的結構:
1. Read request
2. Decode request
3. Process service
4. Encode reply
5. Send reply

經(jīng)典的網(wǎng)絡(luò )服務(wù)的設計如下圖,在每個(gè)線(xiàn)程中完成對數據的處理:

但這種模式在用戶(hù)負載增加時(shí),性能將下降非常的快。我們需要重新尋找一個(gè)新的方案,保持數據處理的流暢,很顯然,事件觸發(fā)機制是最好的解決辦法,當有事件發(fā)生時(shí),會(huì )觸動(dòng)handler,然后開(kāi)始數據的處理。

Reactor模式類(lèi)似于A(yíng)WT中的Event處理:

Reactor模式參與者

1.Reactor 負責響應IO事件,一旦發(fā)生,廣播發(fā)送給相應的Handler去處理,這類(lèi)似于A(yíng)WT的thread
2.Handler 是負責非堵塞行為,類(lèi)似于A(yíng)WT ActionListeners;同時(shí)負責將handlers與event事件綁定,類(lèi)似于A(yíng)WT addActionListener

如圖:

Java的NIO為reactor模式提供了實(shí)現的基礎機制,它的Selector當發(fā)現某個(gè)channel有數據時(shí),會(huì )通過(guò)SlectorKey來(lái)告知我們,在此我們實(shí)現事件和handler的綁定。

我們來(lái)看看Reactor模式代碼:


public class Reactor implements Runnable{

  final Selector selector;
  final ServerSocketChannel serverSocket;

  Reactor(int port) throws IOException {
    selector = Selector.open();
    serverSocket = ServerSocketChannel.open();
    InetSocketAddress address = new InetSocketAddress(InetAddress.getLocalHost(),port);
    serverSocket.socket().bind(address);

    serverSocket.configureBlocking(false);
    //向selector注冊該channel
     SelectionKey sk =serverSocket.register(selector,SelectionKey.OP_ACCEPT);

    logger.debug("-->Start serverSocket.register!");

    //利用sk的attache功能綁定Acceptor 如果有事情,觸發(fā)Acceptor
    sk.attach(new Acceptor());
    logger.debug("-->attach(new Acceptor()!");
  }


  public void run() { // normally in a new Thread
    try {
    while (!Thread.interrupted())
    {
      selector.select();
      Set selected = selector.selectedKeys();
      Iterator it = selected.iterator();
      //Selector如果發(fā)現channel有OP_ACCEPT或READ事件發(fā)生,下列遍歷就會(huì )進(jìn)行。
      while (it.hasNext())
        //來(lái)一個(gè)事件 第一次觸發(fā)一個(gè)accepter線(xiàn)程
        //以后觸發(fā)SocketReadHandler
        dispatch((SelectionKey)(it.next()));
        selected.clear();
      }
    }catch (IOException ex) {
        logger.debug("reactor stop!"+ex);
    }
  }

  //運行Acceptor或SocketReadHandler
  void dispatch(SelectionKey k) {
    Runnable r = (Runnable)(k.attachment());
    if (r != null){
      // r.run();

    }
  }

  class Acceptor implements Runnable { // inner
    public void run() {
    try {
      logger.debug("-->ready for accept!");
      SocketChannel c = serverSocket.accept();
      if (c != null)
        //調用Handler來(lái)處理channel
        new SocketReadHandler(selector, c);
      }
    catch(IOException ex) {
      logger.debug("accept stop!"+ex);
    }
    }
  }
}

以上代碼中巧妙使用了SocketChannel的attach功能,將Hanlder和可能會(huì )發(fā)生事件的channel鏈接在一起,當發(fā)生事件時(shí),可以立即觸發(fā)相應鏈接的Handler。

再看看Handler代碼:

public class SocketReadHandler implements Runnable {

  public static Logger logger = Logger.getLogger(SocketReadHandler.class);

  private Test test=new Test();

  final SocketChannel socket;
  final SelectionKey sk;

   static final int READING = 0, SENDING = 1;
  int state = READING;

  public SocketReadHandler(Selector sel, SocketChannel c)
    throws IOException {

    socket = c;

    socket.configureBlocking(false);
     sk = socket.register(sel, 0);

    //將SelectionKey綁定為本Handler 下一步有事件觸發(fā)時(shí),將調用本類(lèi)的run方法。
    //參看dispatch(SelectionKey k)
    sk.attach(this);

    //同時(shí)將SelectionKey標記為可讀,以便讀取。
    sk.interestOps(SelectionKey.OP_READ);
    sel.wakeup();
  }

  public void run() {
    try{
    // test.read(socket,input);
      readRequest() ;
    }catch(Exception ex){
    logger.debug("readRequest error"+ex);
    }
  }


/**
* 處理讀取data
* @param key
* @throws Exception
*/
private void readRequest() throws Exception {

  ByteBuffer input = ByteBuffer.allocate(1024);
  input.clear();
  try{

    int bytesRead = socket.read(input);

    ......

    //激活線(xiàn)程池 處理這些request
    requestHandle(new Request(socket,btt));

    .....


  }catch(Exception e) {
  }

}

注意在Handler里面又執行了一次attach,這樣,覆蓋前面的Acceptor,下次該Handler又有READ事件發(fā)生時(shí),將直接觸發(fā)Handler.從而開(kāi)始了數據的讀 處理 寫(xiě) 發(fā)出等流程處理。

將數據讀出后,可以將這些數據處理線(xiàn)程做成一個(gè)線(xiàn)程池,這樣,數據讀出后,立即扔到線(xiàn)程池中,這樣加速處理速度:

更進(jìn)一步,我們可以使用多個(gè)Selector分別處理連接和讀事件。

一個(gè)高性能的Java網(wǎng)絡(luò )服務(wù)機制就要形成,激動(dòng)人心的集群并行計算即將實(shí)現。

Scalable IO in Java原文

本站僅提供存儲服務(wù),所有內容均由用戶(hù)發(fā)布,如發(fā)現有害或侵權內容,請點(diǎn)擊舉報。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
《Scalable IO in Java》筆記
Reactor模型
NIO+reactor模式的網(wǎng)路服務(wù)器設計方案
Socket通道續3---io框架模型演化
Netty源碼解讀(四)Netty與Reactor模式 | 并發(fā)編程網(wǎng)
Reactor模式詳解
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導長(cháng)圖 關(guān)注 下載文章
綁定賬號成功
后續可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服

欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久