ThreadPoolExecutor

来源:互联网 发布:windows系统安装工具 编辑:程序博客网 时间:2024/05/30 23:23

1.线程池的基本使用

任务类task(Runnable实现类):

package ThreadPoolExecute.helloworld;import java.io.Serializable;/** * 线程池执行的任务 */class task implements Runnable, Serializable{    private static final long serialVersionUID = 0;    private static int consumeTaskSleepTime = 2000;    // 保存任务所需要的数据    private Object threadPoolTaskData;    task(Object tasks)    {        this.threadPoolTaskData = tasks;    }    public void run()    {        // 处理一个任务,这里的处理方式太简单了,仅仅是一个打印语句        System.out.println(Thread.currentThread().getName()+"start");        try        {            // //便于观察,等待一段时间            Thread.sleep(consumeTaskSleepTime);        }        catch (Exception e)        {            e.printStackTrace();        }        threadPoolTaskData = null;    }    public Object getTask()    {        return this.threadPoolTaskData;    }}

线程池测试类:

package ThreadPoolExecute.helloworld;import java.util.concurrent.ArrayBlockingQueue;import java.util.concurrent.ThreadPoolExecutor;import java.util.concurrent.TimeUnit;/* * 1.构造方法参数说明(见程序代码) * 2.execute(Runnable)方法被添加到线程池,任务就是一个 Runnable类型的对象,任务的执行方法就是 Runnable类型对象的run()方法 * 3.execute(Runnable)添加时有多种情况: * 如果此时线程池中的数量小于corePoolSize,即使线程池中的线程都处于空闲状态,也要创建新的线程来处理被添加的任务 * 如果此时线程池中的数量等于 corePoolSize,但是缓冲队列 workQueue未满,那么任务被放入缓冲队列 * 如果此时线程池中的数量大于corePoolSize,缓冲队列workQueue满,并且线程池中的数量小于maximumPoolSize,建新的线程来处理被添加的任务 * 如果此时线程池中的数量大于corePoolSize,缓冲队列workQueue满,并且线程池中的数量等于maximumPoolSize,那么通过 handler所指定的策略来处理此任务。 * 也就是说处理任务的优先级为: * 核心线程corePoolSize、任务队列workQueue、最大线程maximumPoolSize,如果三者都满了,使用handler处理被拒绝的任务 *  *  * 4.当线程池中的线程数量大于 corePoolSize时,如果某线程空闲时间超过keepAliveTime,线程将被终止,这样,线程池可以动态的调整池中的线程数 *  * 5.参数的可选值 * unit(线程池维护线程所允许的空闲时间的单位): * java.util.concurrent.TimeUnit.NANOSECONDS *java.util.concurrent.TimeUnit.MICROSECONDS * java.util.concurrent.TimeUnit.MILLISECONDS * java.util.concurrent.TimeUnit.SECONDS *  * workQueue(线程池所使用的缓冲队列 )--BlockingQueue的子类 * ArrayBlockingQueue *  *  * handler(线程池对拒绝任务的处理策略) * ThreadPoolExecutor.AbortPolicy()--抛出java.util.concurrent.RejectedExecutionException异常  * ThreadPoolExecutor.CallerRunsPolicy()--重试添加当前的任务,他会自动重复调用execute()方法  * ThreadPoolExecutor.DiscardOldestPolicy()--抛弃旧的任务  * ThreadPoolExecutor.DiscardPolicy()--抛弃当前的任务 *  * 6.调整 produceTaskSleepTime和 consumeTaskSleepTime的大小来实现对派发任务和处理任务的速度的控制 *       调整workQueue中所指的数据,再加上调整任务丢弃策略,换上其他三种策略,就可以看出不同策略下的不同处理方式 *  */public class thread_poor_execute{    private static int produceTaskSleepTime = 2;    private static int produceTaskMaxNumber = 10;    public static void main(String[] args)    {        // 构造一个线程池        ThreadPoolExecutor threadPool = new ThreadPoolExecutor(        2,//corePoolSize:线程池维护的最少线程数量        4,//maximumPoolSize:线程池维护的最多线程数量        3,//keepAliveTime:线程池维护线程所允许的空闲时间          TimeUnit.SECONDS,//TimeUnit unit:线程池维护线程所允许的空闲时间的单位        new ArrayBlockingQueue<Runnable>(3),//BlockingQueue<Runnable> workQueue: 线程池所使用的缓冲队列         new ThreadPoolExecutor.DiscardOldestPolicy());//RejectedExecutionHandler handler:线程池对拒绝任务的处理策略        //创建10个线程,分别添加到线程池中        for (int i = 1; i <= produceTaskMaxNumber; i++)        {            try            {                // 产生一个任务,并将其加入到线程池                String name = "task@ " + i;                threadPool.execute(new task(name));                // 便于观察,等待一段时间                Thread.sleep(produceTaskSleepTime);            }            catch (Exception e)            {                e.printStackTrace();            }        }    }}


总结:

线程池设置了最大a最小b个线程,某一时刻线程池中有m(a~b之间)个线程,调用execute将多个任务(Runnable实现类对象)添加到pool中,加入线程池中此刻有5个线程工作,添加了100个任务,这100个任务就是由这5个线程交替执行的

某一时刻任务1和任务100都由线程1执行,下一时刻可能任务1由线程2执行,而任务100由线程5执行。线程池就是有这么一个简单的功能,内部实现确实稍稍有点复杂,不想写了,等下次研究透了在写吧


原创粉丝点击