使用线程池实现为多个客户端提供Echo服务
import java.io.*; import java.net.ServerSocket; import java.net.Socket; import java.util.Scanner; import java.util.concurrent.*; public class ThreadEchoServer { public static void main(String[] args) { ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(2, 3, 300, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(1), Executors.defaultThreadFactory(), new ThreadPoolExecutor.CallerRunsPolicy()); try(ServerSocket s = new ServerSocket(8189)){ while(true){ Socket incoming = s.accept(); Runnable r = new ThreadedEchoHandler(incoming); System.out.println("当前线程池大小:"+threadPoolExecutor.getPoolSize()); System.out.println("阻塞队列容量:"+threadPoolExecutor.getQueue().size()); threadPoolExecutor.execute(r); } }catch (IOException e){ e.printStackTrace(); } } } class ThreadedEchoHandler implements Runnable{ private Socket incoming; public ThreadedEchoHandler(Socket incomingSocket){ incoming = incomingSocket; } @Override public void run() { try(InputStream inStream = incoming.getInputStream(); OutputStream outStream = incoming.getOutputStream()) { Scanner in = new Scanner(inStream, "UTF-8"); PrintWriter out = new PrintWriter(new OutputStreamWriter(outStream, "UTF-8"), true); out.println("hello!, enter BYE to exit"); boolean done = false; while(!done && in.hasNextLine()){ String line = in.nextLine(); out.println("Echo: " + line); if(line.trim().equals("BYE")) done = true; } } catch (IOException e) { e.printStackTrace(); } } }
可以看到依次打开四个窗口,输入命令telnet localhost 8189,其中第三个连接被阻塞了。原因是设置的线程池核心线程数为2,最大线程数为3,阻塞队列的大小为1.
当线程数大于核心线程数,且阻塞队列不满时,新提交的线程会进入阻塞队列中。
如果新提交一个任务,阻塞队列已满,且小于最大线程数,线程池会新建线程来执行。
可以看到当第一个线程任务执行完毕后,第三个打开的窗口连接到了服务端,也就是开始执行阻塞队列中的任务了。
也算是复习了一下线程池的一些参数了