Chapter1 章节结构
1. 传统IO 特点 IO阻塞
package com.john.netty.learn.ch01.oio;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.handler;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class OioServer {
public OioServer(int port) {
this.port = port;
}
public void start() {
try {
serverSocket = new ServerSocket(this.port);
System.out.println("服务启动");
while (true) {
Socket socket = serverSocket.accept();
if (socket == null) {
continue;
}
System.out.println("来了一个客户");
handler(socket); //线程堵塞
}
} catch (Throwable e) {
}
}
private void handler(Socket socket) {
InputStream is = null;
OutputStream os = null;
byte[] bytes = new byte[10];
try {
is = socket.getInputStream();
int length = -1;
while ((length = is.read(bytes)) != -1) {
System.out.println(new String(bytes, 0, length));
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
is.close();
} catch (IOException e) {
}
}
}
private int port;
private ServerSocket serverSocket = null;
public static void main(String[] args) {
new OioServer(1000).start();
}
}
解决方法: 用线程池可以有多个客户端连接,但是非常消耗性能,每一个客户都需要一个线程提供独立服务。
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class OioServer {
private ExecutorService executorService = Executors.newFixedThreadPool(5);
public OioServer(int port) {
this.port = port;
}
public void start() {
try {
serverSocket = new ServerSocket(this.port);
System.out.println("服务启动");
while (true) {
Socket socket = serverSocket.accept();
if (socket == null) {
continue;
}
System.out.println("来了一个客户");
executorService.submit(new Runnable() {
@Override
public void run() {
handler(socket);
}
});
}
} catch (Throwable e) {
e.printStackTrace();
}
}
private void handler(Socket socket) {
InputStream is = null;
OutputStream os = null;
byte[] bytes = new byte[10];
try {
is = socket.getInputStream();
int length = -1;
while ((length = is.read(bytes)) != -1) {
System.out.println(new String(bytes, 0, length));
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
is.close();
} catch (IOException e) {
}
}
}
private int port;
private ServerSocket serverSocket = null;
public static void main(String[] args) {
new OioServer(1000).start();
}
}
餐厅例子: 每一个客户一个服务员,及其浪费线程。
所有源码下载 :https://download.youkuaiyun.com/download/netcobol/10308871