三种线程创建方式
- 继承 Thread 类重写 run 方法
- 实现Runnable接口的run方法
- 使用Callable和Future创建线程
继承 Thread 类重写 run 方法
线程创建方式 | 创建过程 | 优势 | 劣势 |
---|---|---|---|
继承 Thread 类重写 run 方法 | 1)创建实例,此时该线程未被启动执行。MyThread thread= new MyThread (); 2)调用该实例的start方法启动线程 thread .start();,达到就绪状态(已经获取了除CPU资源的其他资源),等待获取CPU资源才会处于运行状态。 3)run方法执行完毕,线程处于终止状态。 | 1)run() 方法获取当前线程直接使用 this ,无需使用 Thread. currentThread() 方法。 | 1)Java 不支持多继承,如果继承了 Thread 类, 那么就不能再继承其他类。 2)任务与代码没有分离,当多个线程执行一样的任务时需要多份任务代码,而 Runnable 则没有这个限制 。 3)任务没有返回值 |
实现 Runnable 接口 run 方法
线程创建方式 | 创建过程 | 优势 | 劣势 |
---|---|---|---|
实现Runnable 接口 run 方法 | 1)创建实例RunableTask task =new RunableTask (),此时该线程未被启动执行。 2)使用创建的task对象作为任务创建了一个线程并启动它 new Thread(task) .start() | 1)可以 RunableTask 添加参数进行任务区分,达到不共用一个task逻辑 2)可以继承其他类 | 1)任务没有返回值 |
使用Callable和Future创建线程
// 创建任务类
public stat class CallerTask implemets Callable<返回类型> {
@Override
public 返回类型 call() throws Exception{
return 返回类型值;
}
}
// 具体使用:
// 创建异步任务
FutureTask<返回类型> futureTask =new FutureTask<>(new CallerTask()) ;
// 启动线程
new Thread(futureTask).start();
// 等待任务执行完毕,并返回结果
返回类型 result = futureTask.get();
CallerTask 类实现了 Callable 接口的 call ()方法 。
- 在 main 函数内首先创建了FutrueTask 对象(构造函数为CallerTask 实例)
- 使用创建的FutrueTask 对象作为任务创建了一个线程并启动它
- 通过futureTask.get()等待任务执行完毕并返回结果
总结:
使用继承方式的好处是方便传参,可以在子类里添加成员变量,通过set方法设置参数或者通过构造函数进行传递。不好的是不可以继承其他类,不能拿到任务的返回结果。
使用Runnable方式,只能使用主线程里被声明为final的变量。可以继承其他类,不能拿到任务的返回结果。
使用Callable和Future方式,可以拿到任务的返回结果。