2015年2月4日 星期三

Java Thread Pool

Logdown -> http://villebez.logdown.com/posts/2014/10/16/238021
這篇主要還是延續前篇 JAVA POP3 Server 實作,改善效能問題。
其實我的問題就如同 Gossip@Openhome 的 Design Pattern: Thread Pool 模式 教學說明的第一段,如下:
「在 Thread-Per-Message 模式 中,每次請求來到,就建立一個新的執行緒,用完就不再使用,然後執行緒的建立需要系統資源,對於一個接受許多請求的情況,不斷的建立新執行緒,會導致系統 效能的降低。」
有興趣看 Thread Pool 的演進,可以看看以下這三個 Design Pattern
  1. Thread-Per-Message 模式
  2. Worker Thread 模式
  3. Thread Pool 模式
但是這裡我沒有要實作 Thread Pool 模式,我只是要了解原理跟用途就好,因為 JavaSE 5.0 以後,已經有 util 可以直接達到 Thread Pool的效果了,也就是 concurrent util
所以為了這個效能問題呢,將程式改寫,並加上 Monitor Thread 程式來監看 Thread Pool 使用情形。

不廢話,直接看程式,其他自己看 java api


...

    public void run() {
        // creating the ThreadPoolExecutor

        ThreadPoolExecutor executorPool = new ThreadPoolExecutor(50, 300, 10,
                TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(30),
                Executors.defaultThreadFactory());
        // start the monitoring thread

        MonitorThread monitor = new MonitorThread(executorPool, 5);
        Thread monitorThread = new Thread(monitor);
        monitorThread.start();

        try {
            while (keeprunning) {
                Socket clientSocket = listenSocket.accept();
                clientSocket.setSoTimeout(10000);
                clientSocket.setTcpNoDelay(true);
                executorPool.execute(new manageconnection(clientSocket));
            }
        } catch (IOException excpt) {
            log.error("Sorry ,Failed I/O:" + excpt);
        }
    }

...


MonitorThread.java


public class MonitorThread implements Runnable {
    private static final Logger log = Logger.getLogger(MonitorThread.class);
    private ThreadPoolExecutor executor;

    private int seconds;

    private boolean run = true;
    
    public void shutdown() {
        this.run = false;
    }

    public MonitorThread(ThreadPoolExecutor executor, int delay) {
        this.executor = executor;
        this.seconds = delay;
    }

    @Override
    public void run() {
        while (run) {
            log.info(String
                    .format("[monitor] [%d/%d] Active: %d, Completed: %d, Task: %d, isShutdown: %s, isTerminated: %s",
                            this.executor.getPoolSize(),
                            this.executor.getCorePoolSize(),
                            this.executor.getActiveCount(),
                            this.executor.getCompletedTaskCount(),
                            this.executor.getTaskCount(),
                            this.executor.isShutdown(),
                            this.executor.isTerminated()));
            try {
                Thread.sleep(seconds * 1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

    }
}


output
[monitor] [50/50] Active: 1, Completed: 3, Task: 4, isShutdown: false, isTerminated: false

沒有留言:

張貼留言