概述
前面已经学习过两种创建线程的方式了:
- 实现Runnable接口,实现其中run方法。
- 继承Thread,重写其中run方法。
今天我们来认识第三种创建线程的方式,它具有返回值和可抛出异常。
Java 5.0 在 java.util.concurrent 提供了一个新的创建执行线程的方式:Callable 接口
- Callable 接口类似于 Runnable,两者都是为那些其实例可能被另一个线程执行的类设计的。但是 Runnable 不会返回结果,并且无法抛出经过检查的异常。
- Callable 需要依赖FutureTask ,FutureTask 也可以用作闭锁。
测试代码
TestCallable.java
package juc.callable;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
/*
* Callabe接口创建线程:
* 1.与实现Runnable接口的区别:
* Callable新增了返回值(在接口的泛型处体现),新增了可抛出异常
* 2.使用步骤:
* 2.1.实现Callable接口,实现其中的call方法。
* 2.2.新建实现Callable接口的对象。
* 2.3.新建FutureTask对象,其中参数是Callable接口对应的对象。
* 2.4.新建Thread对象,其中参数是FutureTask对象。
* 2.5.执行线程:Thread对象.start方法。
* 2.6.FutureTask对象.get方法等待返回值。
* 3.FutureTask对象:
* 3.1.用于接收Callable执行线程完毕之后的结果。
* 3.2.在线程结果没有被get到的时候,它会阻塞后面的内容,也可以用于闭锁。
*/
public class TestCallable {
public static void main(String[] args) {
long sum = 0;
// 2.2.新建实现Callable接口的对象。
ThreadDemo threadDemo = new ThreadDemo();
// 2.3.新建FutureTask对象,其中参数是Callable接口对应的对象。
FutureTask<Integer> task = new FutureTask<>(threadDemo);
// 2.4.新建Thread对象,其中参数是FutureTask对象。
// 2.5.执行线程:Thread对象.start方法。
new Thread(task).start();
try {
// 2.6.FutureTask对象.get方法等待返回值。
sum = task.get();
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
// 3.2.在线程结果没有被get到的时候,它会阻塞后面的内容,也可以用于闭锁。
System.out.println("总和是: " + sum);
}
/*
* 结果:
* ……
* 999997
* 999998
* 999999
* 总和是: 1783293664
*/
}
// 2.1.实现Callable接口,实现其中的call方法。
// 创建线程方式三:实现Callable接口
class ThreadDemo implements Callable<Integer> {
// 新增返回值(接口的泛型上体现),新增了可抛出异常
@Override
public Integer call() throws Exception {
int sum = 0;
for (int i = 0; i < 1000000; i++) {
sum += i;
System.out.println(i);
}
return sum;
}
}
// 创建线程方式二:继承Thread
class ThreadDemo1 extends Thread {
@Override
public void run() {
}
}
// 创建线程方式一:实现Runnable接口
class ThreadDemo2 implements Runnable {
@Override
public void run() {
}
}
其它
关注下方微信公众号,
回复:
JUC.code
欢迎加入交流群:451826376
更多信息:www.itcourse.top