前言
多线程和并发这两个东西真的是向往已久, 总是有一种神秘的感觉, 想去探索一波, 又担心水平不够无法驾驭想以读书笔记的方式来写, 但是又觉得缺少自己的一些思考; 但是在没有足够并发编程经验的情况下又没法去写出很深刻的东西, 毕竟没有踩过坑所以在阅读 spring 源码的同时, 也想抽点时间来看一看 JUC 的东西, 关于这块只能说是记录自己学习 JUC 的一个过程, 尝试用一些具体的代码 demo 来加深理解所以就把本系列写成 初识 - 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 提供了可以获取异步执行结果的方法, 区别于 Runnable 的 run 方法, 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 接口是线程池实现的顶级接口, 其和 spring 中的 BeanFactory 所承担的角色差不多, 就是提供顶级的功能约束, 具体实现交于不同子类来完成
- 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);
- }
下面是 JUC 中 Executor 框架的整体结构:
- 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;
- }
ExecutorService 再 Executor 接口的基础上扩展了对线程池状态的控制以及提交任务执行的超时控制线程池的基本功能还不够完善, 不能真正的具备处理具体业务的能力 (毕竟是个接口, O(_)O 哈哈~)
来源: https://juejin.im/post/5a7578a05188257a59119951