Java并发编程核心方法与框架-Future和Callable的使用
Callable接口与Runnable接口对比的主要优点是Callable接口可以通过Future获取返回值。但是Future接口调用get()方法取得结果时是阻塞的,如果调用Future对象的get()方法时任务尚未执行完,则调用get()方法时一直阻塞到此任务完成。如果前面的任务耗时很多,则后面的任务调用get()方法就呈阻塞状态,大大影响运行效率。主线程不能保证首先获得的是最先完成任务的返回值,这是Future的缺点。
public class MyCallable implements Callable<String> {
private int age;
public MyCallable(int age) {
super();
this.age = age;
}
@Override
public String call() throws Exception {
TimeUnit.SECONDS.sleep(8);
return "返回值 年龄是:" + age;
}
public static void main(String[] args) {
MyCallable myCallable = new MyCallable(22);
int corePoolSize = 2;
int maximumPoolSize = 3;
int keepAliveTime = 5;
TimeUnit unit = TimeUnit.SECONDS;
LinkedBlockingDeque<Runnable> workQueue = new LinkedBlockingDeque<Runnable>();
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue);
Future<String> future = threadPoolExecutor.submit(myCallable);
try {
System.out.println(System.currentTimeMillis());
String string = future.get();
System.out.println(string);
System.out.println(System.currentTimeMillis());
} catch (Exception e) {
e.printStackTrace();
}
}
}
打印结果如下:
1470904027660
返回值 年龄是:22
1470904035663
从打印结果看,可见get()方法具有阻塞的特性。
方法submit()不仅可以传入Callable对象,还可以传入Runnable对象,submit()方法支持有返回值和无返回值。
public class Run {
public static void main(String[] args) {
try {
Runnable runnable = new Runnable() {
@Override
public void run() {
System.out.println("打印的信息");
}
};
ExecutorService executorService = Executors.newCachedThreadPool();
Future future = executorService.submit(runnable);
System.out.println(future.get() + " " + future.isDone());
} catch (Exception e) {
e.printStackTrace();
}
}
}
打印结果如下:
打印的信息
null true
方法isDone()无阻塞特性。
使用ExecutorService接口中的方法submit(Runnable, T result)
public class User {
private String username;
private String password;
//省略getter setter
}
public class MyRunnable implements Runnable {
private User user;
public MyRunnable(User user) {
super();
this.user = user;
}
@Override
public void run() {
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
user.setUsername("admin");
user.setPassword("123456");
}
}
public class Main {
FutureTask task;
public static void main(String[] args) {
try {
User user = new User();
MyRunnable myRunnable = new MyRunnable(user);
int corePoolSize = 10;
int maximumPoolSize = 10;
int keepAliveTime = 10;
TimeUnit unit = TimeUnit.SECONDS;
LinkedBlockingDeque<Runnable> workQueue = new LinkedBlockingDeque<>();
ThreadPoolExecutor executor = new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue);
Future<User> future = executor.submit(myRunnable, user);
System.out.println(System.currentTimeMillis());
System.out.println(user.getUsername() + "-" + user.getPassword());
user = future.get();
System.out.println(user.getUsername() + "-" + user.getPassword());
System.out.println(System.currentTimeMillis());
} catch (Exception e) {
e.printStackTrace();
}
}
}
控制台打印结果如下:
1470908214853
null-null
admin-123456
1470908216855
Java并发编程核心方法与框架-Future和Callable的使用的更多相关文章
- Java并发编程核心方法与框架-CountDownLatch的使用
Java多线程编程中经常会碰到这样一种场景:某个线程需要等待一个或多个线程操作结束(或达到某种状态)才开始执行.比如裁判员需要等待运动员准备好后才发送开始指令,运动员要等裁判员发送开始指令后才开始比赛 ...
- Java并发编程核心方法与框架-Fork-Join分治编程(一)
在JDK1.7版本中提供了Fork-Join并行执行任务框架,它的主要作用是把大任务分割成若干个小任务,再对每个小任务得到的结果进行汇总,这种开发方法也叫做分治编程,可以极大地利用CPU资源,提高任务 ...
- Java并发编程核心方法与框架-CompletionService的使用
接口CompletionService的功能是以异步的方式一边生产新的任务,一边处理已完成任务的结果,这样可以将执行任务与处理任务分离.使用submit()执行任务,使用take取得已完成的任务,并按 ...
- Java并发编程核心方法与框架-TheadPoolExecutor的使用
类ThreadPoolExecutor最常使用的构造方法是 ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAli ...
- Java并发编程核心方法与框架-Semaphore的使用
Semaphore中文含义是信号.信号系统,这个类的主要作用就是限制线程并发数量.如果不限制线程并发数量,CPU资源很快就会被耗尽,每个线程执行的任务会相当缓慢,因为CPU要把时间片分配给不同的线程对 ...
- Java并发编程核心方法与框架-ScheduledExecutorService的使用
类SchedukedExecutorService的主要作用是可以将定时任务与线程池功能结合. 使用Callable延迟运行(有返回值) public class MyCallableA implem ...
- Java并发编程核心方法与框架-ExecutorService的使用
在ThreadPoolExecutor中使用ExecutorService中的方法 方法invokeAny()和invokeAll()具有阻塞特性 方法invokeAny()取得第一个完成任务的结果值 ...
- Java并发编程核心方法与框架-Executors的使用
合理利用线程池能够带来三个好处 降低资源消耗.通过重复利用已创建的线程降低线程创建和销毁造成的消耗. 提高响应速度.当任务到达时,任务可以不需要等到线程创建就能立即执行. 提高线程的可管理性.线程是稀 ...
- Java并发编程核心方法与框架-phaser的使用
arriveAndAwaitAdvance()方法 arriveAndAwaitAdvance()作用是当前线程已经到达屏障,在此等待一段时间,等条件满足后继续向下一个屏障执行. public cla ...
随机推荐
- 由多线程引起的map取值为null的分析
昨天写了一个多线程的程序,却发现了一个很奇特的问题,就是我的map对象明明put了,可是get的时候竟然会取到null,而且尝试多次,有时候成功,有时候取到null,并不确定. 程序代码如下: pub ...
- js 中 == 和=== 有什么区别?
第一个是相等符:第二个全等符: 其中第一个在比较的时候,会进行类型转换,而第二个则不会, alert('55' == 55);//truealert('55' === 55);//false
- bzoj2938: [Poi2000]病毒
建AC自动机,把所有病毒的节点都删掉,dfs判有没有环,有环就找得到. #include <iostream> #include <cstdio> #include <c ...
- 【BZOJ-4316】小C的独立集 仙人掌DP + 最大独立集
4316: 小C的独立集 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 57 Solved: 41[Submit][Status][Discuss] ...
- [IOS Tableview] cell自定义view显示错误问题
问题介绍:按照tableviewcell的tag自定义cell的view显示的时候,会出现拖动时显示错误情况(在Tableview的范围超出屏幕范围需要滑动的情况下). 我做的是一个下载界面,我为了简 ...
- Pythonn new-style class and old-style class
In [1]: class old(): ...: a = 1 ...: In [2]: o = old() In [3]: o.__class__ Out[3]: <class __main_ ...
- Mac & XCode 使用技巧总结
Mac OS 是基于UNIX 的操作系统. 一 基本技巧 1. 允许安装任何来源的APP 系统偏好设置 -> 安全性和隐私 -> 通用 选择”允许从以下位置下载的应用程序“ 中的 “任何来 ...
- FIFA halts 2026 bids amid scandal 国际足联在丑闻期间停止2026年足球世界杯申请
FIFA halts 2026 bids amid scandal 国际足联在丑闻期间停止2026年足球世界杯申请 But official insists 2018 Cup will stay in ...
- 【原】react中如何使用jquery插件
react的思想是虚拟dom,提倡最好较少dom的操作,可是我们在写网页的时候,有些复杂的交互还是离不开jquery插件的.而且当你把jquery直接拿来用的时候,你会发觉会报错,要么是找不到那个插件 ...
- Android Studio MultiDex 分包碰到的坑
前天准备发包了,测试完毕,打好正式签名包,装到手机上,运行不起来. 网上查了大量资料,都没有解决方案. log显示如下: 04-26 10:07:57.727 1538-1538/? I/MultiD ...