netty01-bio介绍

1.传统BIO线程模型/阻塞

1.1 单线程实现

来看下传统bio(单线程)的代码示例:
package com.hotpot.day01.bio;

import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;

/**
 * 描述:传统Socket阻塞案例
 * @author: myx
 * @date: 2018/2/6 0006
 * Copyright © 2017-ganinfo. All rights reserved.
 */
public class TraditionalSocketDemo{
	@SuppressWarnings("resource")
	public static void main(String[] args) throws IOException {
		ServerSocket serverSocket = new ServerSocket(7777);
		System.out.println("服务端启动...");
		while(true){
			// 获取socket套接字
			// accept()阻塞点
			Socket socket = serverSocket.accept();
			System.out.println("有新客户端连接上来了...");
			// 获取客户端输入流
			InputStream is = socket.getInputStream();
			byte[] b = new byte[1024];
			while(true){
				// 循环读取数据
				// read() 阻塞点
				int data = is.read(b);
				if(data != -1){
					String info = new String(b,0,data,"GBK");
					System.out.println(info);
				}else{
					break;
				}
			}
		}
	}
}
采用一问一达的方式(一个服务端只能为一个客户端服务),就像是一个餐厅只能服务一个客人。

1.2 多线程实现

package com.hotpot.day01.bio;

import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;

/**
 * 描述:传统bio多线程版本
 * @author: myx
 * @date: 2018/2/6 0006
 * Copyright © 2017-ganinfo. All rights reserved.
 */
public class TraditionalSocketDemo2{
	@SuppressWarnings("resource")
	public static void main(String[] args) throws IOException {
		ServerSocket serverSocket = new ServerSocket(7777);
		System.out.println("服务端启动...");
		while(true){
			// 获取socket套接字
			// accept()阻塞点
			Socket socket = serverSocket.accept();
			System.out.println("有新客户端连接上来了...");
			new Thread(new Runnable() {
				@Override
				public void run() {
					try {
						// 获取客户端输入流
						InputStream is = socket.getInputStream();
						byte[] b = new byte[1024];
						while(true){
							// 循环读取数据
							// read() 阻塞点
							int data = is.read(b);
							if(data != -1){
								String info = new String(b,0,data,"GBK");
								System.out.println(info);
							}else{
								break;
							}
						}
					} catch (Exception e) {
						e.printStackTrace();
					}
				}
			}).start();
		}
	}
}
多线程结构图:

缺点:
当用户一直增长,对于服务的压力也是越来越大,会导致整个服务挂掉,就像是一个餐厅为了服务N个可能请了N个服务生,自然餐厅最后会黄调

1.3 线程池实现

package com.hotpot.day01.bio;

import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ExecutorService;

import static java.util.concurrent.Executors.newFixedThreadPool;

/**
 * 描述:传统BIO 多线程伪异步IO
 * @author: myx
 * @date: 2018/2/6 0006
 * Copyright © 2017-ganinfo. All rights reserved.
 */
public class TraditionalSocketMultiThreadDemo {
	@SuppressWarnings("resource")
	public static void main(String[] args) throws IOException {
//		ExecutorService threadPool = Executors.newCachedThreadPool();// 线程池,缓存,无限大  m:m = 请求:线程  n:m  n=>m=1
		ExecutorService threadPool = newFixedThreadPool(100); // 请求:线程 = n:m (n>m)
		ServerSocket serverSocket = new ServerSocket(7777);
		System.out.println("服务端启动...");
		while (true) {
			// 获取socket套接字
			// accept()阻塞点
			Socket socket = serverSocket.accept();
			threadPool.execute(new Runnable() {
				@Override
				public void run() {
					try {
						System.out.println("有新客户端连接上来了...");
						// 获取客户端输入流
						InputStream is = socket.getInputStream();
						byte[] b = new byte[1024];
						while (true) {
							// 循环读取数据
							// read() 阻塞点
							int data = is.read(b);
							if (data != -1) {
								String info = new String(b, 0, data, "GBK");
								System.out.println(info);
							} else {
								break;
							}
						}
					} catch (IOException e) {
						e.printStackTrace();
					}
				}
			});
		}
	}
}


缺点(伪异步IO):
当线程池已经用完所有线程,再来新的请求会等待,就像一个餐厅来了100个只有50个服务生,50人需要等待,会有客人不满意。

1.4 BIO问题总结

  • 每当一个新的客户端请求接入时,服务端必须创建一个线程来处理这条链路
  • 如果在高性能高并发场景下肯定是没法用的










猜你喜欢

转载自blog.csdn.net/qq_31463999/article/details/79272860