应用实例:
(1)使用BIO模型编写一个服务器端,监听6666端口,当有一个客户端连接时,就启动一个线程与之通讯。
(2)要求使用线程池机制改善,可以连接多个客户端。
(3)服务端可以接受客户端发送的数据(telnet即可)
package com.songguo.bio;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
public class BIOServer {
public static void main(String[] args) throws Exception{
//1.创建一个线程池
Executor cachedThreadPool= Executors.newCachedThreadPool();
//2.创建一个ServiceSocket
ServerSocket serverSocket=new ServerSocket(6666);
System.out.println("服务启动");
while(true){
System.out.println("等待链接");
//监听,等待客户端连接
final Socket socket = serverSocket.accept();
System.out.println("客户端已链接");
//创建一个线程与之通讯
cachedThreadPool.execute(new Runnable() {//重写run方法
@Override
public void run() {
//可以和客户端通讯
handle(socket);
}
});
}
}
public static void handle(Socket socket){
byte[] bytes=new byte[1024];
try {
System.out.println("线程ID:"+Thread.currentThread().getId());
System.out.println("线程名:"+Thread.currentThread().getName());
//通过socket获取输入流
InputStream inputStream = socket.getInputStream();
while(true)
{
int read=inputStream.read(bytes);
if(read!=-1)//没有读取完毕
{
System.out.println(new String(bytes,0,read));//把字节数组装成相应的String
}
else{
break;
}
}
}catch (Exception e){
System.out.println("捕获异常");
}finally {
System.out.println("关闭和客户端的连接");
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
BIO问题分析:
(1)每个请求都需要创建独立的线程处理连接。
(2)并发量大的时候,需要创建大量的线程处理连接,系统资源占用大。
(3)连接建立后,如果当前线程暂没有数据可读,线程会阻塞在read操作上,线程资源浪费。