多线程编程学习十(线程池原理).
一、线程池工作流程
- 线程池判断核心线程池里的线程是否都在执行任务。如果不是,则创建一个新的工作线程来执行任务(需要获得全局锁)。如果核心线程池里的线程都在执行任务,则进入下个流程。
- 线程池判断工作队列是否已满。如果工作队列没有满,则将新提交的任务存储在这个工作队列里。如果工作队列满了,则进入下个流程。
- 线程池判断线程池的线程是否都处于工作状态。如果没有,则创建一个新的工作线程来执行任务(需要获得全局锁)。如果已经满了,则交给饱和策略(例如抛出异常)来处理这个任务。
tips:这样的设计方案,可以避免频繁的线程创建,大部分的工作任务都会停留在第二步。
二、Executor 框架
在 Java 中,线程池的知识是要从 Executor 框架展开。Executor 框架主要由三部分组成:
1. 任务
包括 Runnable 接口或 Callable 接口。Runnable 接口无返回值,Callable 有返回值。
// Runnable 和 Callable 都可以直接被 ThreadPoolExecutor 和 ScheduledThreadPoolExecutor 执行
Runnable runnable = () -> System.out.println(123);
// Executors 可以将 Runnable 转化成 Callable
Callable<Object> callable = Executors.callable(runnable);
Callable<String> success = Executors.callable(runnable, "success");
2. 任务的执行
包括任务执行机制的核心接口 Executor、继承自 Executor 的 ExecutorService 接口以及实现 ExecutorService 的 ThreadPoolExecutor 和 ScheduledThreadPoolExecutor。
ThreadPoolExecutor 是线程池的核心实现类,用来执行被提交的任务。其中 ThreadPoolExecutor 的原理就是上面介绍的线程池工作流程。
ScheduledThreadPoolExecutor 继承自 ThreadPoolExecutor ,可以在给定的延迟后执行任务,或者定期执行任务。
Executors 是创建 ThreadPoolExecutor 和 ScheduledThreadPoolExecutor 的工厂类。
static ExecutorService executorService = Executors.newFixedThreadPool(5);
3. 异步计算的结果
包括 Future 接口以及实现 Future 的 FutureTask 类。
// 执行 Runnable
executorService.execute(runnable);
// 执行 Callable
Future<Object> submit = executorService.submit(callable);
// Future 的 get 方法会阻塞线程直到完成
System.out.println(submit.get());
Future<String> future = executorService.submit(success);
System.out.println(future.get());
当 FutureTask 处于未启动状态时,执行 FutureTask.cancel() 方法将导致此任务永远不会被执行;
当 FutureTask 处于已启动状态时,执行FutureTask.cancel(true)方法将以中断执行此任务线程的方式来试图停止任务;
当 FutureTask 处于已启动状态时,执行FutureTask.cancel(false)方法将不会对正在执行此任务的线程产生影响(让正在执行的任务运行完成);
当 FutureTask 处于已完成状态时,执行FutureTask.cancel()方法将返回false。
Executor框架的使用示意图如下:
相关链接:10问10答:你真的了解线程池吗?
相关文章
- C#多线程学习(四) 多线程的自动管理(线程池)
- Android多线程研究(1)——线程基础及源代码剖析
- 多线程系列 使用多线程的安全问题
- java 多线程并发 synchronized 同步机制及方式
- Java多线程CyclicBarrier学习
- 线程池运用实例——一次错误的多线程程序设计以及修复过程
- 《C#多线程编程实战(原书第2版)》——3.4 线程池与并行度
- Java高并发与多线程理解
- java 多线程 4 线程池
- Linux 的多线程编程的高效开发经验
- 《C++多线程编程实战》——2.8 线程的用法
- 【多线程】线程安全保护机制
- iOS多线程全套:线程生命周期,多线程的四种解决方案,线程安全问题,GCD的使用,NSOperation的使用
- Java学习-080-多线程13:利用Lambda表达式实现线程类的定义
- Java多线程之线程状态转换图
- Linux环境下多线程C/C++程序的内存问题诊断
- 再次探讨 WinForms 多线程开发
- 多线程基础(六)GCD基础
- Java多线程基础(一)---线程安全(synchronized关键字this锁和class锁分析)
- Java多线程-线程创建的3种方式
- Java多线程-线程3大不安全案例