4.1.4 线程池
package com.suifeng.tcpip.chapter4;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.logging.Logger;
/**
* 采用自定义线程池的方式实现多任务处理
* @author Suifeng
*
*/
public class TCPEchoServerPool
{
public static void main(String[] args) throws IOException
{
if(args.length != 2)
{
throw new IllegalArgumentException("Parameter:<Port> <PoolSize>");
}
// 服务器侦听的端口号
int serverPort = Integer.parseInt(args[0]);
// 自定义线程池的大小
int poolSize = Integer.parseInt(args[1]);
// 日志记录器
final Logger logger = Logger.getLogger("practical");
final ServerSocket serverSocket = new ServerSocket(serverPort);
logger.info("Server is started!!!!");
/*
* 每个线程都反复循环,从(共享的)ServerSocket实例接收客户端连接。
* 当多个线程同时调用同一个ServerSocket实例的accept()方法时,
* 它们都将阻塞等待,直到一个新的连接成功建立。然后系统选择一个线程,
* 新建立的连接对应的Socket实例则只在选中的线程中返回。
* 其他线程则继续阻塞,直到成功建立下一个连接和选中另一个幸运的线程。
*
* */
for(int i = 0; i < poolSize; i++)
{
Thread t = new Thread()
{
@Override
public void run()
{
while(true)
{
try
{
// 各个线程阻塞等待,知道有一个客户端连过来,当线程进行处理,其他的线程继续处理
Socket socket = serverSocket.accept();
EchoProtocol.handleEchoClient(socket, logger);
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
};
t.start();
logger.info("Thread "+t.getName()+" has started!!!");
}
}
}
启动服务器端,监听39393端口

注:服务器已启动就会启动两个线程等待客户端发送数据
启动客户端,同一客户一线程一样,使用第二章的客户端代码

查看服务器端
注:现在使用第一个线程处理的(Thread-1)
再次启动客户端

再次查看服务器端

此次使用的是第二个线程(Thread-2)进行处理的