java 多线程:Callable接口;FutureTask类实现对象【Thread、Runnable、Callable三种方式实现多线程的区别】
Callable接口介绍:
Java5开始,Java提供了Callable接口,像是Runnable接口的增强版,Callable接口提供了一个 call()方法可以作为线执行体.
call()方法比run()方法功更强大。call()方法可以有返回值,call()方法可以抛出异常
实现方法:
- 创建Callable接口实现类对象
- 创建FutureTask类实现对象
- 创建Thread类实现对象
- 调用Thread类实现对象start()方法提交线程任务
示例:
import java.util.HashSet; import java.util.Set; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.FutureTask; /** * @ClassName CallableExample * @projectName: object1 * @author: Zhangmingda * @description: XXX * date: 2021/4/19. */ public class CallableExample { public static void main(String[] args) { /** * 实现Callable接口必须重写call方法。 */ Callable<Integer> callable = new Callable<Integer>() { @Override public Integer call() throws Exception { return null; } }; /** * 该接口又是函数式接口只有一个call方法,可以用lambda表达式替代如下 */ Callable<Integer> callable1 = () -> null; /** * 测试多线程实际应用:计算1+2+3+...+100的和 * 接口实现类对象callable2 */ Callable<Integer> callable2 = () -> { int num = 0; for(int i=1; i<=100; i++){ num +=i; } System.out.println("I am "+ Thread.currentThread().getName() + " My result:" + num); return num; }; //使用Set集合存储计划任务FutureTask类对象,便于获取结果 Set<FutureTask> futureTasks = new HashSet<>(); //跑10个线程 for(int i=0; i<10; i++){ //通过callable接口实现类 创建计划任务FutureTask实现类对象 FutureTask<Integer> futureTask = new FutureTask<>(callable2); //向集合中添加计划任务类对象 futureTasks.add(futureTask); //通过FutureTask实现类创建线程实体类Thread类对象,并提交给jvm运行 new Thread(futureTask).start(); } //获取每个任务的结果计算总和 int resultCount =0; for(FutureTask<Integer> futureTask :futureTasks){ try { //计算所有任务结果总和 resultCount += futureTask.get(); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } } System.out.println("10个任务计算总和:" + resultCount); } }
Thread、Runnable、Callable三种方式实现多线程的优势区别
- 继承:采用Thread方式实现的线程不能继承其他父类,采用Runnable和Callable接口的可以继承其他父类,但是编程上采用Thread的方式可以直接使用getName()方法,而采用Runnable和Callable接口的方式需要先获取Thread.currentThread();
- 共享:采用Runnable和Callable的方式,可以多个线程公用一个Target对象,而采用Thread的方式不能,所以非常适合多个相同线程来处理同一份资源的情况
- 返回值:如果需要线程有返回值的需要使用Callable的方式。
posted on 2021-04-19 17:35 zhangmingda 阅读(117) 评论(0) 编辑 收藏 举报