生活随笔
收集整理的這篇文章主要介紹了
nio-马士兵
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
tcp四次揮手
配置快速關閉time_wait 狀態的系統參數可以快速利用
NIO是非阻塞的多路復用IO
非阻塞IO
多路復用
非阻塞io和多路復用的區別
- 非阻塞: 每次都是通過read來判斷有數據,即使IO中沒有數據,也會利用一個線程不停的對應一個IO 不停的read
- 非阻塞+多路復用io: 一次調用回去所以io的狀態,通過狀態判斷哪個Io中有數據,再建立對應線程去這個io中讀取數據。
package com
.bjmashibing
.system
.io
;import java
.io
.IOException
;
import java
.net
.InetSocketAddress
;
import java
.nio
.ByteBuffer
;
import java
.nio
.channels
.SelectionKey
;
import java
.nio
.channels
.Selector
;
import java
.nio
.channels
.ServerSocketChannel
;
import java
.nio
.channels
.SocketChannel
;
import java
.util
.Iterator
;
import java
.util
.Set
;
import java
.util
.concurrent
.BlockingQueue
;
import java
.util
.concurrent
.LinkedBlockingQueue
;
import java
.util
.concurrent
.atomic
.AtomicInteger
;public class SocketMultiplexingThreads {private ServerSocketChannel server
= null
;private Selector selector1
= null
;private Selector selector2
= null
;private Selector selector3
= null
;int port
= 9090;public void initServer() {try {server
= ServerSocketChannel
.open();server
.configureBlocking(false);server
.bind(new InetSocketAddress(port
));selector1
= Selector
.open();selector2
= Selector
.open();selector3
= Selector
.open();server
.register(selector1
, SelectionKey
.OP_ACCEPT
);} catch (IOException e
) {e
.printStackTrace();}}public static void main(String
[] args
) {SocketMultiplexingThreads service
= new SocketMultiplexingThreads();service
.initServer();NioThread T1
= new NioThread(service
.selector1
,2);NioThread T2
= new NioThread(service
.selector2
);NioThread T3
= new NioThread(service
.selector3
);T1
.start();try {Thread
.sleep(1000);} catch (InterruptedException e
) {e
.printStackTrace();}T2
.start();T3
.start();System
.out
.println("服務器啟動了。。。。。");try {System
.in
.read();} catch (IOException e
) {e
.printStackTrace();}}
}class NioThread extends Thread {Selector selector
= null
;static int selectors
= 0;int id
= 0;volatile static BlockingQueue
<SocketChannel>[] queue
;static AtomicInteger idx
= new AtomicInteger();NioThread(Selector sel
,int n
) {this.selector
= sel
;this.selectors
= n
;queue
=new LinkedBlockingQueue[selectors
];for (int i
= 0; i
< n
; i
++) {queue
[i
] = new LinkedBlockingQueue<>();}System
.out
.println("Boss 啟動");}NioThread(Selector sel
) {this.selector
= sel
;id
= idx
.getAndIncrement() % selectors
;System
.out
.println("worker: "+id
+" 啟動");}@Overridepublic void run() {try {while (true) {while (selector
.select(10) > 0) {Set
<SelectionKey> selectionKeys
= selector
.selectedKeys();Iterator
<SelectionKey> iter
= selectionKeys
.iterator();while (iter
.hasNext()) {SelectionKey key
= iter
.next();iter
.remove();if (key
.isAcceptable()) {acceptHandler(key
);} else if (key
.isReadable()) {readHandler(key
);}}}if( ! queue
[id
].isEmpty()) {ByteBuffer buffer
= ByteBuffer
.allocate(8192);SocketChannel client
= queue
[id
].take();client
.register(selector
, SelectionKey
.OP_READ
, buffer
);System
.out
.println("-------------------------------------------");System
.out
.println("新客戶端:" + client
.socket().getPort()+"分配到:"+ (id
));System
.out
.println("-------------------------------------------");}}} catch (IOException e
) {e
.printStackTrace();} catch (InterruptedException e
) {e
.printStackTrace();}}public void acceptHandler(SelectionKey key
) {try {ServerSocketChannel ssc
= (ServerSocketChannel
) key
.channel();SocketChannel client
= ssc
.accept();client
.configureBlocking(false);int num
= idx
.getAndIncrement() % selectors
;queue
[num
].add(client
);} catch (IOException e
) {e
.printStackTrace();}}public void readHandler(SelectionKey key
) {SocketChannel client
= (SocketChannel
) key
.channel();ByteBuffer buffer
= (ByteBuffer
) key
.attachment();buffer
.clear();int read
= 0;try {while (true) {read
= client
.read(buffer
);if (read
> 0) {buffer
.flip();while (buffer
.hasRemaining()) {client
.write(buffer
);}buffer
.clear();} else if (read
== 0) {break;} else {client
.close();break;}}} catch (IOException e
) {e
.printStackTrace();}}}
總結
以上是生活随笔為你收集整理的nio-马士兵的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。