一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第11天,点击查看活动详情 。
01-线程状态
-
NEW
// 线程创建后,线程的状态为 NEW Thread t = new Thread(new Runnable() {...}); -
RUNNABLE
// 调用线程的 start 方法后,线程状态变为 RUNNABLE t.start();注:此时线程正在被 JVM 执行,但是并不见得真的在 CPU 上执行,有可能在等待 CPU 的时间片
-
BLOCKED
线程等待 monitor 锁时,会进入到阻塞状态。
-
WAITING / TIMED_WAITING
- Object.wait() / Thread.join() / LockSupport.park() 导致线程进入 WAITING 状态,即等待其他的线程调用 Object.notify() / Object.notifyAll() / 线程执行完毕 / LockSupport.unpark()
- 带超时版本的上述方法会使线程进入 TIMED_WAITING 状态
- 此外,Thread.sleep() 也会使线程进入到 TIMED_WAITING 状态
-
TERMINATED
线程执行完毕后(正常或异常退出),该线程进入到 TERMINATED 状态
02-创建线程的方式
-
继承 Thread 类
class MyThreadA extends Thread { @Override public void run() { // .... } } -
实现 Runnable 接口
class MyThreadB implements Runnable { @Override public void run() { // ... } } -
实现 Callable 接口
class MyThreadC implements Callable { @Override public Object call() throws Exception { return null; } }
注:实现 Runnable 与 继承 Thread 类的区别是,前者更灵活、方便;Runnable 与 Callable 的区别是,前者的 run 方法无法返回值,而后者的 call 方法可以设定返回值。
03-线程的启动方式
-
Thread.start() 方法(结合 02 中线程创建方式)
// 继承 Thread 或实现 Runnable 接口 Thread ta = new MyThreadA(); ta.start(); Thread tb = new Thread(new MyThreadB()); tb.start(); // 实现 Callable 接口 FutureTask<Object> ft = new FutureTask<>(new MyThreadC()); Thread tc = new Thread(ft, "name"); tc.start(); -
ExecutorService 框架
- 可通过工具类 Executors 快捷地创建不同类型的线程池(阿里开发手册并不推荐这么做,原因是容易忽略线程池的内部逻辑,从而造成性能问题,推荐使用 ThreadPoolExecutor 方式)
- cached thread pool
- fixed thread pool
- single thread pool
- scheduled thread pool
- work stealing pool
- 提交任务到线程池(Runnable 或 Callable 对象)
- execute,无返回值
- submit,有返回值,Future (更多信息参考[1])
- 可通过工具类 Executors 快捷地创建不同类型的线程池(阿里开发手册并不推荐这么做,原因是容易忽略线程池的内部逻辑,从而造成性能问题,推荐使用 ThreadPoolExecutor 方式)
-
CompletableFuture,更多信息参考[2]
CompletableFuture.supplyAsync(() -> "Hello");