FutureTask的使用示例
程序员文章站
2022-04-03 14:06:40
...
今天看书,有关于 FutureTask 的介绍,感觉还蛮有意思的,可以用它来做一些比较花时间的事情。下面打个通俗的比方来说明一下它的用处:
比如,早上一大早的去公交站台等公交,但那该死的公交20分钟才一班。如果一直死等公交,那么这20分钟无疑就被浪费了。我们可以利用这20分钟,去买个韭菜饼,再买一盒豆浆,然后一边吃一边等。这样就明显提高了时间的利用率。
下面给出一个段简单的代码来说明一下它的使用:
public class Preloader { private final FutureTask<Long> future = new FutureTask<Long>(new Callable<Long>() { @Override public Long call() throws Exception { Thread.currentThread().setName("Thread(3)"); System.out.println(Thread.currentThread().getName() + ": simulate a latency "); try { Thread.sleep(5000); } catch (Exception e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + ": the latency is over"); return Math.round(Math.random() * 1000); } }); private final Thread loader = new Thread(future); public void start() { System.out.println(Thread.currentThread().getName() + ": start the loader"); loader.start(); System.out.println(Thread.currentThread().getName() + ": loader started"); } public Long get() { try { System.out.println(Thread.currentThread().getName() + ": begin to get"); long start = System.currentTimeMillis(); Long result = future.get(); System.out.println(Thread.currentThread().getName() + ": got result: " + result); System.out.println(Thread.currentThread().getName() + ": spent time: " + (System.currentTimeMillis() - start)); return result; } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + ": got nothing"); return null; } public static void main(String[] args) { Thread.currentThread().setName("Thread(main)"); final Preloader pl = new Preloader(); pl.start(); // try to get the result before the latency is over new Thread(new Runnable() { @Override public void run() { Thread.currentThread().setName("Thread(1)"); pl.get(); } }).start(); // try to get the result after the latency is over new Thread(new Runnable() { @Override public void run() { Thread.currentThread().setName("Thread(2)"); try { Thread.sleep(6000); pl.get(); } catch (InterruptedException e) { e.printStackTrace(); } } }).start(); } }
以上代码的运行结果为:
main: start the loader main: loader started Thread(3): simulate a latency Thread(1): begin to get Thread(3): the latency is over Thread(1): got result: 917 Thread(1): spent time: 5006 Thread(2): begin to get Thread(2): got result: 917 Thread(2): spent time: 0
通过上面运行的结果,我们可以得到以下结论:
① 在FutureTask执行完了之前(即call执行完了之前),去进行get的话,将被会一直阻塞至FutureTask执行完了才会返回。
② FutureTask执行完了之后,再调用get的话,会立刻返回相应的结果
③ FutureTask只会执行一次,所以,多次调用get方法,返回的值始终是一样的。
推荐阅读
-
C语言--getchar()的使用
-
HBase 系列(六)——HBase Java API 的基本使用
-
创建基于ASP.NET core 3.1 的RazorPagesMovie项目(一)-创建和使用默认的模板
-
FineReport的概念和使用讲解
-
flask与Flask-CORS的使用
-
使用NuGet将我们的ASP.NET Core类库打包并将程序包(类库)发布到NuGet平台上进行管理
-
Python爬虫使用selenium爬取qq群的成员信息(全自动实现自动登陆)
-
php foreach循环中使用引用的问题
-
vue-router的简单使用
-
倒计时cocos定时器schude使用的过程中 帧率浮动较大导致执行时机不准确的问题解决