多线程的另外两种创建方式
线程的创建总共有四种方式,分别是继承Thread类、实现Runnable接口、实现Callable接口和通过线程池创建
在前面我已经学习了前面两种创建线程的方式,今天来学习一下后面两种创建线程的方式。Callable接口和线程池技术是在JDK5.0以后添加的。
1、实现Callable接口
实现步骤:
1. 定义一个类实现Callable接口
2. 实现Callable接口的call()方法
3. 创建子类实例对象
4. 把这个实例对象当做参数传入FutureTask的构造方法中
5. 将FutureTask的实例对象当做参数传入Thread类的构造方法中
6. 调用Thread的start()方法,启动线程
7. 通过FutureTask获取线程的结果
代码演示:
public class ThreadTest3 {
public static void main(String[] args) {
FutureTask<Integer> futureTask = new FutureTask<>(new CallableThread());
new Thread(futureTask).start();
try {
Integer integer = futureTask.get();
System.out.println(integer);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
for(int i = 0; i < 10; i++){
System.out.println(Thread.currentThread().getName()+"-->"+i);
}
}
}
class CallableThread implements Callable<Integer>{
@Override
public Integer call() throws Exception {
int sum = 0;
for (int i = 0; i < 100; i++) {
System.out.println(Thread.currentThread().getName()+"-->"+i);
sum += i;
}
return sum;
}
}
使用Callable的优点
- 支持泛型
- 可以打印异常信息
- 可以有返回值
2、通过线程池创建线程
想要了解线程池首先需要了解池的思想。
(1)什么是池?
池相当于是一个房间,你可以在房间里放一些工具。当你需要使用工具的时候直接从房间里拿出来使用就行了。
(2)为什么要使用池?
通过线程池可以避免重复的去创建、销毁线程,实现线程的重复利用。
使用线程池需要两个接口:ExecutorService和Executors
Executors用来创建线程池
ExecutorService就相当于是线程池
实现步骤:
- 创建一个提供线程数量的线程池
- 通过execute()或submit()方法来启动线程。
- 关闭线程池
代码演示:
public class ThreadTest4 {
public static void main(String[] args) {
ExecutorService service = Executors.newFixedThreadPool(10);
service.execute(new PoolThread());//用于Runnable接口
service.shutdown();
}
}
class PoolThread implements Runnable{
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println(i);
}
}
}
使用线程池的优点:
- 提高响应速度(减少了创建线程的时间)
- 降低资源消耗(线程可以重复利用,不用每次都创建)
- 方便管理线程(可以管理线程池中的线程数量等)
总结
创建线程的四种方法已经学完了,但是用的还是比较少。在后面我会多谢谢练习来巩固关于多线程的知识。