nio实现一个线程可以处理多个请求,降低cpu的使用率,简单的实现思想就是使用缓冲区然后用一个集合收集多个请求,把多个请求变成一个队列
,让一个线程来处理这个队列,非阻塞并且可以减少cpu要增加线程的消耗。(个人简单理解,有错请直接指出,感谢)
redis的底层是使用nio的多路复用来实现对tcp连接的io复用,能够非常好的实现对高并发的支持与解决多线程安全问题。原理是将多个不同channel统一的交给selector(选择器管理)
nio在不同的操作系统下实现存在区别,在window下使用的是select轮询机制,在linux系统下是采用的epoll
window的机制时间复杂度是o(n),有可能出现空轮询,而linux采用的是回调机制,只对活跃的socket实现主动的回调,时间复杂度是o(1)
package entity;
import java.io.BufferedReader;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.nio.charset.Charset;
import java.util.ArrayList;
/**
* @author haixin
* @time 2019-11-24
*/
public class NIOserver {
public static ArrayList<SocketChannel> socketlist = new ArrayList<>();
public static ByteBuffer byteBuffer = ByteBuffer.allocate(512);
public static void main(String[] args) {
try {
ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
serverSocketChannel.bind(new InetSocketAddress(8080));
serverSocketChannel.configureBlocking(false);
while (true){
SocketChannel socketaccept = serverSocketChannel.accept();
if (socketaccept != null) {
socketaccept.configureBlocking(false);
socketlist.add(socketaccept);
}
for (SocketChannel scl : socketlist) {
int read = scl.read(byteBuffer);
if (read > 0 ){
byteBuffer.flip();
Charset charset = Charset.forName("utf-8");
String receiveText = charset.newDecoder().decode(byteBuffer.asReadOnlyBuffer()).toString();
System.out.println(Thread.currentThread().getName() + "receiveText: " + receiveText);
socketlist.remove(scl);
版权声明:本文为chordimp原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。