天天看点

利用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)

文章转自庄周梦蝶  ,原文发布时间