天天看點

利用Doug Lea的并發包實作帶逾時機制的線程池

import edu.oswego.cs.dl.util.concurrent.boundedbuffer;

import edu.oswego.cs.dl.util.concurrent.pooledexecutor;

/**

 * <p>類說明:線程池</p>

 * <p>注意事項:</p>

 * <pre></pre>

 * <p>建立日期:sep 7, 2007 1:25:33 pm</p>

* @author:dennis zane

 * @version $id:$

 */

public class mythreadpool{

    private static pooledexecutor exec = new pooledexecutor(new boundedbuffer(

            20), 30);

    static {

        exec.setkeepalivetime(1000 * 60 * 5);

        exec.createthreads(5);

        exec.setminimumpoolsize(4);

    }

    public static void execute(final runnable r)  throws interruptedexception{

        exec.execute(r);

    }

    public static void shutdown() {

        exec.shutdownafterprocessingcurrentlyqueuedtasks();

        exec = null;

}

    靜态初始化并設定一個poolexecutor,設定空閑線程的存活時間為5分鐘,設定最小線程數為4,最大線程數為30,一開始建立5個線程以待使用(根據各自的應用調整這些參數),另外提供了shutdown方法以供serveltcontextlistener的contextdestroyed方法調用以關閉線程池。那麼,結合timedcallable來實作送出線程的逾時機制,調用類似:

           //設定逾時時間

           private static final long timeout = 1000;

           ......

       try{

           callable callable = new callable() {

                public object call() {

                    return new yourprogram().run();                   

                }

            };

            timedcallable timedcallable = new timedcallable(callable, timeout);

            futureresult future = new futureresult();

            runnable cmd = future.setter(timedcallable);

            //送出給線程池來執行

            mythreadpool.execute(cmd);

            //擷取任務結果

            yourobject obj= (yourobject) future.get();

            ......

         } catch (interruptedexception e) {

            if (e instanceof timeoutexception) {

                 log.error("任務逾時");

                  ...

             }

         }catch(invocationtargetexception e)

         {

            //清理任務..

         }

         ......

假設n-cpu是cpu個數,u是目标cpu使用率,w/c是任務的等待時間與計算時間的比率,那麼最優的池大小等于:

n-threads=n-cpu*u*(1+w/c)

文章轉自莊周夢蝶  ,原文釋出時間