NIO: synchronous non-blocking IO
Source: BIO is a synchronous blocking IO operation, when the thread when processing tasks, waiting for the other party will block the thread is finished, in order to improve the efficiency ,, after JDK1.4, the introduction of NIO to improve communications performance data
NIO Reactor design pattern used, the focal point is registered Selector, NIO has three main components: Channel (channel), Buffer (buffer), Selector (selector)
Reactor design pattern: Reactor mode is a passive event processing mode, an event that is triggered when a specific event occurs, reference, https://blog.csdn.net/feimataxue/article/details/7642638 , HTTPS: // www.cnblogs.com/bitkevin/p/5724410.html
NIO uses a round-robin fashion to observe whether the event is finished, such as: A let B print a file, BIO will always be waiting for the return to B, do not do other things during his own, and will continue to ask NIO B is completed, when not completed its process, until completion B
Channel (channel): Channel is an object, which can read and write data
Selector (Object Selector): Selector is an object that can be registered to a number Channel, listen for events that occur on each Channel, and Channel reader can decide the case based on events
Code for this implementation example :( reference available on the network)
NIO client implementation:
package com.learn.nio.client; import com.study.info.HostInfo; import com.study.util.InputUtil; import java.net.InetSocketAddress; import java.nio.ByteBuffer; import java.nio.channels.SocketChannel; public class NIOEchoClient { public static void main(String[] args) throws Exception{ SocketChannel clientChannel = SocketChannel.open(); clientChannel.connect(new InetSocketAddress(HostInfo.HOST_NAME,HostInfo.PORT)); ByteBuffer buffer = ByteBuffer.allocate(50); boolean flag = true; while (flag){ buffer.clear(); INPUT String = InputUtil.getString ( "Please enter the information to be transmitted:" ) .trim (); buffer.put (input.getBytes ()); // can buffer buffer.flip (); // reset buffer clientChannel.write (Buffer); // send data buffer.clear (); int Read = clientChannel.read (Buffer); buffer.flip(); System.err.print(new String(buffer.array(), 0, read)); if("byebye".equalsIgnoreCase(input)){ flag = false; } } clientChannel.close(); } }
NIO server implementation:
package com.learn.nio.server; import com.study.info.HostInfo; 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.ExecutorService; import java.util.concurrent.Executors; public class NIOEchoServer { private static class EchoClientHandle implements Runnable { // client Private the SocketChannel ClientChannel; // loop end flag Private Boolean In Flag = to true ; public EchoClientHandle (the SocketChannel ClientChannel) { the this .clientChannel = ClientChannel; } @Override public void run() { ByteBuffer byteBuffer = ByteBuffer.allocate(50); try { while (this.flag){ byteBuffer.clear(); int read = this.clientChannel.read(byteBuffer); String msg = new String(byteBuffer.array(), 0, read).trim(); String outMsg = "【Echo】" + msg + "\n"; // 回应信息 if("byebve".equals(msg)){ outMsg = "session ends, see you next time!" ; the this .flag = false ; } byteBuffer.clear(); ByteBuffer.put (outMsg.getBytes ()); // return information into the buffer ByteBuffer.flip (); the this .clientChannel.write (ByteBuffer); // return information } }catch (Exception e){ e.printStackTrace (); } } } public static void main (String [] args) throws Exception { // for performance issues and the response time, set a fixed-size thread pool ExecutorService ExecutorService = Executors.newFixedThreadPool (10 ); // the NIO Channel based control, it is to manage all Selector the Channel ServerSocketChannel ServerSocketChannel = ServerSocketChannel.open (); // set to non-blocking mode serverSocketChannel.configureBlocking ( false ); // set the listening port serverSocketChannel.bind ( new new InetSocketAddress (HostInfo.PORT)); // set up to manage all Channel Selector = Selector Selector Selector.open (); // Sign and the connection setting process serverSocketChannel.register (selector, SelectionKey.OP_ACCEPT); System.out.println ( "service started successfully, the listener port:" + HostInfo.PORT); // the NIO polling, when a request for a connection, then start a thread int keySelect = 0 ; the while ((keySelect = Selector .Select ())> 0 ) { Set<SelectionKey> selectionKeys = selector.selectedKeys(); Iterator<SelectionKey> iterator = selectionKeys.iterator(); while (iterator.hasNext()){ Next the SelectionKey = Iterator.next (); IF (next.isAcceptable ()) { // if it is connected to the SocketChannel Accept = ServerSocketChannel.accept (); IF (! Accept = null ) { executorService.submit(new EchoClientHandle(accept)); } iterator.remove(); } } } executorService.shutdown(); serverSocketChannel.close(); } }
Tools:
package com.study.util; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; public class InputUtil { private static final BufferedReader KEYBOARD_INPUT = new BufferedReader(new InputStreamReader(System.in)); Private InputUtil () { } public static String the getString (String prompt) { Boolean In Flag = to true ; // data receiving flag String STR = null ; the while (In Flag) { System.out.println(prompt); try { STR = KEYBOARD_INPUT.readLine (); // read a line of data IF (STR == null || "" .equals (STR)) { System.out.println ( "data entry errors must not be empty!" ); }else { flag = false; } } catch (IOException e) { e.printStackTrace (); } } return str; } }
package com.study.info; public calss HostInfo { public static final String HOST_NAME = "localhost"; public static final int PORT = 9999; }
NIO structure Reference article: https://www.cnblogs.com/sxkgeek/p/9488703.html#_label2