[Первое знакомство]-JUC·Executor Framework

Java Spring

предисловие

Две вещи многопоточность и параллелизм действительно давно хочется.Всегда какое-то таинственное чувство.Хочу исследовать волну,но переживаю,что уровень не достаточен для управления. Хочу писать в виде читающих заметок, но чувствую, что мне не хватает какого-то собственного мышления, но я не могу писать очень глубокие вещи без достаточного параллельного опыта программирования, ведь я ни разу не ступил на яму. Поэтому, читая исходный код Spring, я также хочу уделить некоторое время тому, чтобы взглянуть на JUC, Об этом можно сказать только, чтобы записать процесс изучения JUC и попытаться использовать некоторые конкретные демонстрации кода для углубления понимания. Поэтому я написал эту серию как «[Первое знакомство]-JUC · XXXX», чтобы открыть дверь в параллельное программирование.

JUC

JUC — это java.util.concurrent, то есть параллельный пакет, предоставляемый java. С точки зрения структуры пакета в JUC это в основном:

  • java.util.concurrent

    Ниже этого пакета находятся в основном пулы потоков, параллельные коллекции и некоторые параллельные классы инструментов. Связанный с этим пул потоков построен на базе Excetor; этому посвящена оставшаяся часть этой статьи.

  • java.util.concurrent.atomic

    Ниже этого пакета находятся некоторые атомарные классы операций, которые считаются параллельными вспомогательными инструментальными классами, а базовая реализация зависит от CAS;

  • java.util.concurrent.locks

    Это можно узнать из названия его роли — предоставлять блокировки.

Классы для каждого модуля JUC

  • общая структура

  • atomic

  • locks

  • параллельный сбор

  • Инструменты параллелизма

  • forkJoin

    fork-join имеет следующие три класса в JUC:

    public class ForkJoinPool extends AbstractExecutorService
    
    public abstract class ForkJoinTask<V> implements Future<V>, Serializable
    
    public class ForkJoinWorkerThread extends Thread
    

Future

Future предоставляет метод для получения результата асинхронного выполнения.В отличие от метода run в Runnable, run не возвращает результат.

public interface Future<V> {
    //取消
    boolean cancel(boolean mayInterruptIfRunning);
    //如果任务完成前被取消,则返回true。
    boolean isCancelled();
    //如果任务执行结束,无论是正常结束或是中途取消还是发生异常,都返回true。
    boolean isDone();
    //获取异步执行的结果,如果没有结果可用,此方法会阻塞直到异步计算完成。
    V get() throws InterruptedException, ExecutionException;
    //获取异步执行结果,如果没有结果可用,此方法会阻塞,但是会有时间限制,
    //如果阻塞时间超过设定的timeout时间,该方法将抛出异常。
    V get(long timeout, TimeUnit unit) throws InterruptedException, 
    ExecutionException, TimeoutException;
}

Callable

Объявлен метод с именем call(), и этот метод может иметь возвращаемое значение V или генерировать исключение.

public interface Callable<V> { 
  V   call()   throws Exception; 
} 

Использование Callable и Future обычно используется в сочетании с нашим пулом потоков.

Executor

Интерфейс Executor — это интерфейс верхнего уровня, реализуемый пулом потоков.Он играет роль, аналогичную роли BeanFactory в Spring.Он обеспечивает функциональные ограничения верхнего уровня, а конкретная реализация завершается различными подклассами.

public interface Executor {
    /**
     * Executes the given command at some time in the future.  The command
     * may execute in a new thread, in a pooled thread, or in the calling
     * thread, at the discretion of the <tt>Executor</tt> implementation.
     *
     * @param command the runnable task
     * @throws RejectedExecutionException if this task cannot be
     * accepted for execution.
     * @throws NullPointerException if command is null
     */
    void execute(Runnable command);
}

Ниже представлена ​​общая структура среды Executor в JUC:

ExecutorService

public interface ExecutorService extends Executor {
    //关闭线程池
    void shutdown();
    
    List<Runnable> shutdownNow();
    //是否为Shutdown状态
    boolean isShutdown();
    //是否为Terminated状态
    boolean isTerminated();
    
    //超过超时时间时,会监测ExecutorService是否已经关闭
    //若关闭则返回true,否则返回false。
    //一般情况下会和shutdown方法组合使用。
    boolean awaitTermination(long timeout, TimeUnit unit)
        throws InterruptedException;
    
    //返回一个Future对象,参数接收的是一个Callable的实现
    //Callable接口中的call()方法有一个返回值,可以返回任务的执行结果
    //区别于Runnable接口中的run()方法(void修饰,没有返回值)。
    <T> Future<T> submit(Callable<T> task);
    
    <T> Future<T> submit(Runnable task, T result);
    //返回一个Future对象,通过返回的Future对象,我们可以检查提交的任务是否执行完成了。 
    Future<?> submit(Runnable task);
    
    //返回一个Future的List,其中对应着每个Callable任务执行后的Future对象。
    <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;
        
        
    //接收参数是一个Callable的集合,
    //返回的是所有Callable集合任务中某一个任务的执行结果
    <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;
}

Основываясь на интерфейсе Executor, ExecutorService расширяет возможности управления состоянием пула потоков и контроля тайм-аута выполнения отправленной задачи. Базовые функции пула потоков недостаточно совершенны, чтобы действительно иметь возможность обрабатывать конкретный бизнес (в конце концов, это интерфейс, O(∩_∩)O, ха-ха~).

Начни статью, учись медленно~