使用线程池实现为多个客户端提供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.

当线程数大于核心线程数,且阻塞队列不满时,新提交的线程会进入阻塞队列中。

如果新提交一个任务,阻塞队列已满,且小于最大线程数,线程池会新建线程来执行。

 

 

 可以看到当第一个线程任务执行完毕后,第三个打开的窗口连接到了服务端,也就是开始执行阻塞队列中的任务了。

也算是复习了一下线程池的一些参数了

posted @ 2020-06-10 17:31  silentteller  阅读(98)  评论(0编辑  收藏