Java并发包源码阅读 - Executor

本文是对Java并发包中Executor接口的翻译介绍, 通过该文, 笔者一方面练习英文, 一方面目的理解JDK源码, 所以根据自己的理解, 可能不是直译, 并且添加一些自己的笔记.

由于是为了自己学习做笔记用, 简单的句子直接跳过不翻译.

An object that executes submitted Runnable tasks.

Executor是用于提交Runnable task的类.

This interface provides a way of decoupling task submission from the mechanics of how each task will be run, including details of thread use, scheduling, etc.

该接口提供了一种将任务提交与每个任务的运行机制分离的方法,包括线程使用、调度等细节。

-- 以前创建线程, 只能通过继承Thread或者实现Runnable接口两种方式, 定义和运行是集中在一起的, 现在Executor提供了一种, 将定义和运行分离的新方式.

An Executor is normally used instead of explicitly creating threads.

Executor通常用来替代显式的创建线程.

-- 意思就是, 不在显式的创建线程了.

For example, rather than invoking new Thread(new(RunnableTask())).start() for each of a set of tasks, you might use:

使用一种直接执行的方式, 而不是new Thread(RunnableTask())).start(), 下面是使用案例

Executor executor = anExecutor;

executor.execute(new RunnableTask1());

executor.execute(new RunnableTask2());

...

However, the Executor interface does not strictly require that execution be asynchronous.

Executor接口并不严格要求执行的任务是异步的.

-- 意思是, 并非只有异步的任务才可以使用Executor, 如果你愿意弄一个直接运行的任务, 也无所谓. 例如下面大师就开始举了个栗子

In the simplest case, an executor can run the submitted task immediately in the caller's thread:

class DirectExecutor implements Executor {

public void execute(Runnable r) {

r.run();

}

}

在上面的简单例子中, executor直接在caller线程中运行了任务

More typically, tasks are executed in some thread other than the caller's thread.

The executor below spawns a new thread for each task.

class ThreadPerTaskExecutor implements Executor {

public void execute(Runnable r) {

new Thread(r).start();

}

}

更加经典典型的用法是, 重新创建一个新线程, 去执行提交过来的任务

Many Executor implementations impose some sort of limitation on how and when tasks are scheduled.

Executor的实现类, 在如何运行调度任务上添加了自己的限制.

The executor below serializes the submission of tasks to a second executor, illustrating a composite executor.

下面的executor, 在执行完提交的Runnable之后, 接着执行了Queue tasks里面的任务, 形成了一个复合的executor

-- 下面的代码中, 就在finally中, 执行完队列中的Runnable任务

-- 意思就是, 通过举例说明, Executor的实现是个性化的, 这个例子就是一个连续任务的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);
     }
   }
 }

The Executor implementations provided in this package implement ExecutorService, which is a more extensive interface.

在当前包中的Executor的实现类多是实现自ExecutorService, ExecutorService一个更加被广泛使用的接口

The ThreadPoolExecutor class provides an extensible thread pool implementation.

ThreadPoolExecutor是一个被广泛使用的线程池,

The Executors class provides convenient factory methods for these Executors.

Executors(注意加了s, 不同与本文的Executor接口)为这些Executor们提供了方面的工厂方法

Memory consistency effects: Actions in a thread prior to submitting a Runnable object to an Executor happen-before its execution begins, perhaps in another thread.


下面是关于Executor的使用Demo

/**
 * 功能说明:初识Executor
 * 运行结果如下;
 *
 * hello executor1
 * MyExecutor1 当前线程名称: main
 * hello executor2
 * MyExecutor2 当前线程名称: Thread_new
 *
 *
 * 思考问题: 为什么大师要在已经有了创建和运行线程的方式下,重复早轮子, 提供一个Executor呢?
 * 回答: 之前的创建线程的方式
 * 1, 继承Thread
 * 2, 实现Runnable接口
 * 这两种方式,定义任务和运行是集中在一起的, Executor只负责运行.
 * 开发人员:@author MaLi
 */
public class MT20_Executor {
    public static void main(String[] args) {
        //方式1, 直接运行, 也就是在caller线程中提交到Executor
        new MyExecutor1().execute(()-> System.out.println("hello executor1"));
        // 方式2, 异步运行
        new MyExecutor2().execute(()-> System.out.println("hello executor2"));
    }

    static class MyExecutor1 implements Executor{

        @Override
        public void execute(Runnable command) {
            //直接运行的方式
            command.run();
            System.out.println("MyExecutor1 当前线程名称: "+ Thread.currentThread().getName());
        }
    }

    static class MyExecutor2 implements Executor{

        @Override
        public void execute(Runnable command) {
            //异步的方式运行提交的新线程
            new Thread(()->{
                command.run();
                System.out.println("MyExecutor2 当前线程名称: "+ Thread.currentThread().getName());
            },"Thread_new").start();
        }
    }
}

猜你喜欢

转载自blog.csdn.net/malipku/article/details/120072835