最后
如果觉得本文对你有帮助的话,不妨给我点个赞,关注一下吧!
}
List<Future<String>> results = new ArrayList<>();
for (int i = 0; i < 3; i++) {
Future<String> future = executor.submit(new Task(8 - i));
results.add(future);
}
boolean flag = true;
while (flag) {
for (Iterator<Future<String>> iter = results.iterator(); iter.hasNext(); ) {
Future<String> future = iter.next();
if (future.isDone()) {
System.out.println(future.get() + "完成:" + new Date());
iter.remove();
}
}
if (results.size() == 0) {
flag = false;
}
}
System.out.println("全部线程执行完毕");
executor.shutdownNow();
}
}
输出结果:
pool-1-thread-2启动:Fri Nov 08 14:12:43 CST 2019
pool-1-thread-1启动:Fri Nov 08 14:12:43 CST 2019
pool-1-thread-3启动:Fri Nov 08 14:12:43 CST 2019
pool-1-thread-3完成:Fri Nov 08 14:12:49 CST 2019
pool-1-thread-2完成:Fri Nov 08 14:12:50 CST 2019
pool-1-thread-1完成:Fri Nov 08 14:12:51 CST 2019
全部线程执行完毕
可以看到,一旦某个线程任务执行结束,其结果能被立即获取到,但代价是程序在不停地循环查询线程任务 isDone 的结果,对cpu消耗比较大。因此,使用Future解决多任务结果,并不是最优的效果。
FutureTask正是为此而存在
[]( )2 FutureTask
=======================================================================
[]( )2.1 FutureTask简介
---------------------------------------------------------------------------
FutureTask类实现了RunnableFuture接口:
public class FutureTask implements RunnableFuture
RunnableFuture接口又继承了Runable和Future
public interface RunnableFuture extends Runnable, Future {
void run();
}
可见,FutureTask既可以作为Runnable被线程执行,又可以作为Future得到Callable的返回值。FutureTask类图如下:
![在这里插入图片描述](https://img-blog.csdnimg.cn/20191107211405190.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L211X3dpbmQ=,size_16,color_FFFFFF,t_70)
下面我们再来看看 FutureTask 工具类。前面我们提到的 Future 是一个接口,而 FutureTask 是一个工具类,这个工具类有两个构造函数:
FutureTask(Callable callable);
FutureTask(Runnable runnable, V result);
[]( )2.2 FutureTask使用示例
-----------------------------------------------------------------------------
使用Callable+FutureTask获取执行结果:
import java.util.concurrent.*;
/**
-
@author guozhengMu
-
@version 1.0
-
@date 2019/11/8 14:17
-
@description
-
@modify
*/
public class FutureTaskTest {
public static void main(String[] args) throws ExecutionException, InterruptedException {
MyTask myTask = new MyTask("hello,", "world-");
//将任务放进FutureTask里
FutureTask<Object> futureTask = new FutureTask<>(myTask);
//采用thread来开启多线程
Thread thread = new Thread(futureTask);
thread.start();
try {
System.out.println(futureTask.get());
} catch (Exception e) {
e.printStackTrace();
}
}
}
class MyTask implements Callable {
private String param1;
private String param2;
//构造函数,用来向task中传递任务的参数
public MyTask(String param1, String param2) {
this.param1 = param1;
this.param2 = param2;
}
//任务执行的动作
@Override
public String call() {
for (int i = 0; i < 5; i++) {
System.out.println(param1 + param2 + i);
}
return "运行完成!";
}
}
输出结果:
hello,world-0
hello,world-1
hello,world-2
hello,world-3
hello,world-4
运行完成!
也可以使用线程池:
import java.util.concurrent.*;
/**
-
@author guozhengMu
-
@version 1.0
-
@date 2019/11/8 14:17
-
@description
-
@modify
*/
public class FutureTaskTest {
public static void main(String[] args) throws InterruptedException, ExecutionException {
// 创建 FutureTask
FutureTask<Integer> futureTask = new FutureTask<>(() -> 1 + 2);
// 创建线程池
ExecutorService executor = Executors.newCachedThreadPool();
// 提交 FutureTask
executor.submit(futureTask);
// 获取计算结果
Integer result = futureTask.get();
System.out.println(result);
executor.shutdown();
}
}
接下来,我们使用FutureTask来实现Future多线程获取任务结果的场景:
import java.util.Date;
import java.util.concurrent.*;
/**
-
@author guozhengMu
-
@version 1.0
-
@date 2019/11/8 14:17
-
@description
-
@modify
*/
public class FutureTaskTest {
public static void main(String[] args) {
ExecutorService executor = Executors.newCachedThreadPool();
for (int i = 0; i < 3; i++) {
Callable<String> callable = new Task(8 - i);
MyFutureTask task = new MyFutureTask(callable);
executor.submit(task);
}
executor.shutdown();
}
}
class MyFutureTask extends FutureTask {
public MyFutureTask(Callable<String> callable) {
super(callable);
}
@Override
protected void done() {
try {
System.out.println(get() + "完成:" + new Date());
} catch (InterruptedException | ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
class Task implements Callable {
private int time;
public Task(int time) {
this.time = time;
}
@Override
public String call() throws InterruptedException {
String name = Thread.currentThread().getName();
System.out.println(name + "启动:" + new Date());
TimeUnit.SECONDS.sleep(time);
return name;
}
}
输出结果:
pool-1-thread-1启动:Fri Nov 08 17:35:26 CST 2019
pool-1-thread-3启动:Fri Nov 08 17:35:26 CST 2019
pool-1-thread-2启动:Fri Nov 08 17:35:26 CST 2019
pool-1-thread-3完成:Fri Nov 08 17:35:32 CST 2019
难道这样就够了吗?不,远远不够!
提前多熟悉阿里往年的面试题肯定是对面试有很大的帮助的,但是作为技术性职业,手里有实打实的技术才是你面对面试官最有用的利器,这是从内在散发出来的自信。
备战阿里时我花的最多的时间就是在学习技术上,占了我所有学习计划中的百分之70,这是一些我学习期间觉得还是很不错的一些学习笔记
我为什么要写这篇文章呢,其实我觉得学习是不能停下脚步的,在网络上和大家一起分享,一起讨论,不单单可以遇到更多一样的人,还可以扩大自己的眼界,学习到更多的技术,我还会在csdn、博客、掘金等网站上分享技术,这也是一种学习的方法。
今天就分享到这里了,谢谢大家的关注,以后会分享更多的干货给大家!
为什么要写这篇文章呢,其实我觉得学习是不能停下脚步的,在网络上和大家一起分享,一起讨论,不单单可以遇到更多一样的人,还可以扩大自己的眼界,学习到更多的技术,我还会在csdn、博客、掘金等网站上分享技术,这也是一种学习的方法。
今天就分享到这里了,谢谢大家的关注,以后会分享更多的干货给大家!
[外链图片转存中…(img-U6GOP6wQ-1715654040360)]
[外链图片转存中…(img-rhs4hlQj-1715654040360)]
[外链图片转存中…(img-yfX5t7CN-1715654040361)]