【J.U.C-executors】执行器框架——Executor接口

Executor框架结构

在这里插入图片描述

  • 线程池任务:Runnable、Callable接口及其实现类;
  • 任务结果:Future接口、其实现类FutureTask;
  • 任务执行:Executor、ExecutorService接口。
    ThreadPoolExecutor和ScheduledThreadPoolExecutor是两个ExecutorService接口的实现类

【线程执行工具】Executor接口

  • 一个执行提交的Runnable任务的对象。该接口提供了一种将『任务本身』与『任务执行』解耦的方法(包括线程使用、调度等细节)。
    我们之前创建任务时,通常需要先创建一个线程,然后调用其start方法来执行:
new Thread(new(RunnableTask())).start()
  • 然而使用Executor我们可以不关注线程的创建等过程:
Executor executor = someExecutor;
executor.execute(new RunnableTask1());
executor.execute(new RunnableTask2());
  • Executor接口并不严格要求异步执行。在最简单的情况下,执行器可以在调用者的线程中立即运行提交的任务:
class DirectExecutor implements Executor {
	public void execute(Runnable r) {
		r.run();
	}
}
  • 更典型的情况是,任务在调用者的线程以外的某个线程中执行。下面的执行程序为每个任务生成一个新线程:
class ThreadPerTaskExecutor implements Executor {
	public void execute(Runnable r) {
		new Thread(r).start();
	}
}
  • 许多Executor实现对任务的调度方式和时间施加了某种限制。下面的执行器将任务的提交序列化到第二个执行器,举例一个复合执行器:
class SerialExecutor implements Executor {
    final Queue<Runnable> tasks = new ArrayDeque<Runnable>();
    final Executor executor;
    Runnable active;

    SerialExecutor(Executor executor) {
        this.executor = executor;
    }

    public synchronized void execute(final Runnable r) {
        tasks.offer(new Runnable() {
            public void run() {
                try {
                    r.run();
                } finally {
                    scheduleNext();
                }
            }
        });
        if (active == null) {
            scheduleNext();
        }
    }

    protected synchronized void scheduleNext() {
        if ((active = tasks.poll()) != null) {
            executor.execute(active);
        }
    }
}

Executor中的方法:

void execute(Runnable command);
  • 在将来的某个时间执行给定的命令。
  • 该命令可以在一个新线程中执行,在一个线程池中执行,或者在调用线程中执行,由 Executor实现决定。

【线程池接口】ExecutorService接口

  • ExecutorService接口继承自Executor接口,是对Executor功能的增强。增强了对任务的控制,同时包括对自身生命周期的管理:
    1. 关闭执行器,禁止任务的提交;
    2. 监视执行器的状态;
    3. 提供对异步任务的支持;
    4. 提供对批处理任务的支持。

ExecutorServer中的方法:

	void shutdown();
	
	List<Runnable> shutdownNow();
	
	boolean isShutdown();
	
	boolean isTerminated();
	
	boolean awaitTermination(long timeout, TimeUnit unit)
	        throws InterruptedException;

    <T> Future<T> submit(Callable<T> task);

    <T> Future<T> submit(Runnable task, T result);
   
    Future<?> submit(Runnable task);

    <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks)
        throws InterruptedException;
        
    <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks,
                                  long timeout, TimeUnit unit)
        throws InterruptedException;
        
    <T> T invokeAny(Collection<? extends Callable<T>> tasks)
        throws InterruptedException, ExecutionException;
        
    <T> T invokeAny(Collection<? extends Callable<T>> tasks,
                    long timeout, TimeUnit unit)
        throws InterruptedException, ExecutionException, TimeoutException;
  • 方法 submit扩展了基本方法 Executor.execute(Runnable),创建并返回一个Future,该Future可用于取消执行和/或等待完成。
  • 方法invokeAny和invokeAll执行最常用的批量执行形式,即执行一组任务,然后等待至少一个或全部任务完成。
  • ExecutorService提供了两种不同的方法来关闭ExecutorService:
    • shutdown方法允许之前提交的任务在终止之前执行
    • shutdownNow方法阻止等待的任务启动,并试图停止当前正在执行的任务。
  • 下面的方法分两个阶段关闭ExecutorService,首先调用shutdown拒绝传入的任务,然后调用shutdownNow(如果需要的话)取消任何滞留的任务:
void shutdownAndAwaitTermination(ExecutorService pool) {
        pool.shutdown(); // Disable new tasks from being submitted
        try {
            // Wait a while for existing tasks to terminate
            if (!pool.awaitTermination(60, TimeUnit.SECONDS)) {
                pool.shutdownNow(); // Cancel currently executing tasks
                // Wait a while for tasks to respond to being cancelled
                if (!pool.awaitTermination(60, TimeUnit.SECONDS))
                    System.err.println("Pool did not terminate");
            }
        } catch (InterruptedException ie) {
            // (Re-)Cancel if current thread also interrupted
            pool.shutdownNow();
            // Preserve interrupt status
            Thread.currentThread().interrupt();
        }
    }

【定时/周期任务执行线程池】ScheduledExecutorService接口

  • ScheduledExecutorService接口是继承自ExecutorService接口,实现的功能是将我们提交给执行器的某些任务,定时或周期性地执行。

ScheduledExecutorService中的方法:

	public ScheduledFuture<?> schedule(Runnable command,
                                       long delay, TimeUnit unit);

    public <V> ScheduledFuture<V> schedule(Callable<V> callable,
                                           long delay, TimeUnit unit);

    public ScheduledFuture<?> scheduleAtFixedRate(Runnable command,
                                                  long initialDelay,
                                                  long period,
                                                  TimeUnit unit);

    public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command,
                                                     long initialDelay,
                                                     long delay,
                                                     TimeUnit unit);
  • 其提供了一系列的schedule的方法,可以在指定的延迟或周期后执行任务。
  • 返回值ScheduledFuture是在future的基础上增加了延迟功能。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值