Executor框架

来源:互联网 发布:windows只能进安全模式 编辑:程序博客网 时间:2024/06/07 16:27

线程池的工作过程:

线程池有核心线程数corePoolSize,最大线程数maximunPoolSize,工作线程Worker放在HashSet中,任务队列(阻塞)workQueue.

当线程池里线程数小于corePoolSize时,线程池创建线程来执行任务,

当线程池里线程数等于corePoolSize,而且任务队列没有满时,任务进入任务队列,

当任务队列也满了的时候,创建线程执行任务,直到线程的数量等于maxNum时,不再创建线程,

如果此时线程的数量等于maxNum,任务队列还是满的,后面的任务将执行策略饱和策略,默认是抛出异常.

当线程空闲时间达到keepAliveTime时,线程会退出,直到线程数量=corePoolSize,如果allowCoreThreadTimeout=true,则会直到线程数量=0.


Executor框架包括Executor,ExecutorService,ScheduleExecutorService,CompletionService(用于异步执行任务),Executors,线程池,各种任务,Future,ScheduleFuture(ScheduleExecutorService执行Callable任务的返回对象).

1,Executor接口:

public interface Executor {    void execute(Runnable var1);}
只有一个execute方法,接受Runnable实例,来执行任务.

2,ExecutorService继承自Executor,提供了关闭自己的方法,以及执行Runnable任务和Callable任务的方法.

public interface ExecutorService extends Executor {    void shutdown();    List<Runnable> shutdownNow();    boolean isShutdown();    boolean isTerminated();    boolean awaitTermination(long var1, TimeUnit var3) throws InterruptedException;    <T> Future<T> submit(Callable<T> var1);    <T> Future<T> submit(Runnable var1, T var2);    Future<?> submit(Runnable var1);    <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> var1) throws InterruptedException;    <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> var1, long var2, TimeUnit var4) throws InterruptedException;    <T> T invokeAny(Collection<? extends Callable<T>> var1) throws InterruptedException, ExecutionException;    <T> T invokeAny(Collection<? extends Callable<T>> var1, long var2, TimeUnit var4) throws InterruptedException, ExecutionException, TimeoutException;}
3,ScheduleExecutorService继承自ExecutorService,提供了定期执行任务的方法.

public interface ScheduledExecutorService extends ExecutorService {    ScheduledFuture<?> schedule(Runnable var1, long var2, TimeUnit var4);    <V> ScheduledFuture<V> schedule(Callable<V> var1, long var2, TimeUnit var4);    ScheduledFuture<?> scheduleAtFixedRate(Runnable var1, long var2, long var4, TimeUnit var6);    ScheduledFuture<?> scheduleWithFixedDelay(Runnable var1, long var2, long var4, TimeUnit var6);}
4,Executors类,创建线程池的类,使用静态方法生成几个不同的线程池.

public class Executors {    public static ExecutorService newFixedThreadPool(int var0) {        return new ThreadPoolExecutor(var0, var0, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue());    }    public static ExecutorService newWorkStealingPool(int var0) {        return new ForkJoinPool(var0, ForkJoinPool.defaultForkJoinWorkerThreadFactory, (UncaughtExceptionHandler)null, true);    }    public static ExecutorService newWorkStealingPool() {        return new ForkJoinPool(Runtime.getRuntime().availableProcessors(), ForkJoinPool.defaultForkJoinWorkerThreadFactory, (UncaughtExceptionHandler)null, true);    }    public static ExecutorService newFixedThreadPool(int var0, ThreadFactory var1) {        return new ThreadPoolExecutor(var0, var0, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue(), var1);    }    public static ExecutorService newSingleThreadExecutor() {        return new Executors.FinalizableDelegatedExecutorService(new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue()));    }    public static ExecutorService newSingleThreadExecutor(ThreadFactory var0) {        return new Executors.FinalizableDelegatedExecutorService(new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue(), var0));    }    public static ExecutorService newCachedThreadPool() {        return new ThreadPoolExecutor(0, 2147483647, 60L, TimeUnit.SECONDS, new SynchronousQueue());    }    public static ExecutorService newCachedThreadPool(ThreadFactory var0) {        return new ThreadPoolExecutor(0, 2147483647, 60L, TimeUnit.SECONDS, new SynchronousQueue(), var0);    }    public static ScheduledExecutorService newSingleThreadScheduledExecutor() {        return new Executors.DelegatedScheduledExecutorService(new ScheduledThreadPoolExecutor(1));    }    public static ScheduledExecutorService newSingleThreadScheduledExecutor(ThreadFactory var0) {        return new Executors.DelegatedScheduledExecutorService(new ScheduledThreadPoolExecutor(1, var0));    }    public static ScheduledExecutorService newScheduledThreadPool(int var0) {        return new ScheduledThreadPoolExecutor(var0);    }    public static ScheduledExecutorService newScheduledThreadPool(int var0, ThreadFactory var1) {        return new ScheduledThreadPoolExecutor(var0, var1);    }    public static ExecutorService unconfigurableExecutorService(ExecutorService var0) {        if(var0 == null) {            throw new NullPointerException();        } else {            return new Executors.DelegatedExecutorService(var0);        }    }    public static ScheduledExecutorService unconfigurableScheduledExecutorService(ScheduledExecutorService var0) {        if(var0 == null) {            throw new NullPointerException();        } else {            return new Executors.DelegatedScheduledExecutorService(var0);        }    }}
CachedTheadPool在程序执行过程中通常会创建与所需数量相同的线程,然后在它回收旧线程时停止创建新线程,因此它是合理的Executor的首选,只有当这种方式会引发问题时(比如需要大量长时间面向连接的线程时),才需要考虑用FixedThreadPool。

5,Executor执行Runnable任务:

public class CachedThreadPoolTest {    public static void main(String[] args){        ExecutorService executorService = Executors.newCachedThreadPool();//      ExecutorService executorService = Executors.newFixedThreadPool(5);//      ExecutorService executorService = Executors.newSingleThreadExecutor();        for (int i = 0; i < 5; i++){            executorService.execute(new TestRunnable());            System.out.println("************* a" + i + " *************");        }        executorService.shutdown();    }}class TestRunnable implements Runnable{    public void run(){        System.out.println(Thread.currentThread().getName() + "线程被调用了");    }}
结果是随机的,选择线程空闲执行任务,没有空闲线程便创建:

************* a0 *************
pool-1-thread-1线程被调用了
************* a1 *************
************* a2 *************
pool-1-thread-1线程被调用了
************* a3 *************
************* a4 *************
pool-1-thread-3线程被调用了
pool-1-thread-1线程被调用了
pool-1-thread-2线程被调用了

6,Executor执行Callable任务

和Runnable不同,Callable任务有返回对象Future.

public class CallableTest{    public static void main(String[] args){        ExecutorService executorService = Executors.newCachedThreadPool();        List<Future<String>> resultList = new ArrayList<>();        //创建10个任务并执行        for (int i = 0; i < 10; i++){            //使用ExecutorService执行Callable类型的任务,并将结果保存在future变量中            Future<String> future = executorService.submit(new TaskWithResult(i));            //将任务执行结果存储到List            resultList.add(future);        }        //遍历任务的结果        for (Future<String> fs : resultList){            try{                while(!fs.isDone());//Future返回如果没有完成,则一直循环等待,直到Future返回完成                System.out.println(fs.get());     //打印各个线程(任务)执行的结果            }catch(InterruptedException e){                e.printStackTrace();            }catch(ExecutionException e){                e.printStackTrace();            }finally{                //启动一次顺序关闭,执行以前提交的任务,但不接受新任务                executorService.shutdown();            }        }    }}class TaskWithResult implements Callable<String> {    private int id;    public TaskWithResult(int id){        this.id = id;    }    /**     * 的具体一旦任务传给ExecutorServicesubmit方法     * 则该方法自在一个线程上     */    public String call() throws Exception {        System.out.println("call()方法被自动调用!!!    " + Thread.currentThread().getName());        //该返回结果将被Futureget方法得到        return "call()方法被自动调用,任务返回的结果是:" + id + "    " + Thread.currentThread().getName();    }}




原创粉丝点击