JAVA多线程
1、进程和线程:进程是资源分配的最小单位,线程是程序执行的最小单位。一个程序至少有一个进程,一个进程至少有一个线程。
2、线程生命周期:线程和进程一样分为五个阶段:创建、就绪、运行、阻塞、终止。
1、新建状态(New):新创建了一个线程对象。
2、就绪状态(Runnable):线程对象创建后,其他线程调用了该对象的start()方法。该状态的线程位于可运行线程池中,变得可运行,等待获取CPU的使用权。
void | start() |
3、运行状态(Running):就绪状态的线程获取了CPU,执行程序代码。
static void | 4、yield() |
4、阻塞状态(Blocked):阻塞状态是线程因为某种原因放弃CPU使用权,暂时停止运行。直到线程进入就绪状态,才有机会转到运行状态。阻塞的情况分三种:
(1)、等待阻塞:运行的线程执行wait()方法,JVM会把该线程放入等待池中。
void | notify() |
void | notifyAll() |
void | wait() |
(2)、同步阻塞:运行的线程在获取对象的同步锁时,若该同步锁被别的线程占用,则JVM会把该线程放入锁池中。
(3)、其他阻塞:运行的线程执行sleep()或join()方法,或者发出了I/O请求时,JVM会把该线程置为阻塞状态。当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入就绪状态。
void | join() |
static void | sleep(long millis) |
5、死亡状态(Dead):线程执行完了或者因异常退出了run()方法,该线程结束生命周期
void | run() |
线程的实现
Java多线程实现方式主要有三种:继承Thread类、实现Runnable接口、使用Callable和Future实现有返回结果的多线程。
Callable 接口类似于 Runnable,两者都是为那些其实例可能被另一个线程执行的类设计的。区别 Runnable 不会返回结果,并且无法抛出经过检查的异常。
1、继承Thread类实现多线程
继承Thread类的方法尽管被我列为一种多线程实现方式,但Thread本质上也是实现了Runnable接口的一个实例,它代表一个线程的实例,并且,启动线程的唯一方法就是通过Thread类的start()实例方法。
2、实现Runnable接口
(1) 创建 Callable 接口的实现类,并实现 run()方法,该 run()方法将作为线程执行体
(2)使用 实现类的对象作为 Thread 对象的 target 创建并启动新线程。
3、使用Callable和Future实现有返回结果的多线程。
(1) 创建 Callable 接口的实现类,并实现 call() 方法,该 call() 方法将作为线程执行体,并且有返回值。
(2)创建 Callable 实现类的实例,使用 FutureTask 类来包装 Callable 对象,该 FutureTask 对象封装了该 Callable 对象的 call() 方法的返回值。
(3)使用 FutureTask 对象作为 Thread 对象的 target 创建并启动新线程。
(4)调用 FutureTask 对象的 get() 方法来获得子线程执行结束后的返回值
FutureTask 包装 Callable 或 Runnable 对象。因为 FutureTask 实现了 Runnable,所以可将 FutureTask 提交给 Executor 执行。