Java 线程池(Callable+Future 模式)
Java 通过 Executors 提供四种线程池
1)newCachedThreadPool 创建一个可缓存线程池, 如果线程池长度超过处理需要, 可灵活回收空闲线程, 若无可回收, 则新建线程.
2)newFixedThreadPool 创建一个定长线程池, 可控制线程最大并发数, 超出的线程会在队列中等待.
3)newScheduledThreadPool 创建一个定长线程池, 支持定时及周期性任务执行.
4)newSingleThreadExecutor 创建一个单线程化的线程池, 它只会用唯一的工作线程来执行任务, 保证所有任务按照指定顺序 (FIFO, LIFO, 优先级) 执行.
在多线程的开发中往往会遇到这种情况: 主线程需要知道子线程的运行结果, 以便确定如何执行任务. JDK1.5 以后就提供了 Callable 和 Future, 通过它们可以在任务执行完毕之后得到任务执行结果.
步骤:
1)任务类实现 Callable 接口
2)创建线程池: ExecutorService es = Executors.newCachedThreadPool();
3)执行任务: chuju cj = new chuju();Future<Boolean> future = es.submit(cj);
4)获取子线程中任务的执行结果: future.get()
下面通过实例简单说下其用法:
场景: 假如你想做饭, 但是没有厨具, 也没有食材. 网上购买厨具比较方便, 食材去超市买更放心, 即买出具, 买食材, 这两个任务异步执行, 买好后才能去做饭.
- 1)chuju
- public class chuju implements Callable<Boolean>{
- @Override
- public Boolean call() throws Exception {
- try{
- System.out.println("买厨具");
- Thread.sleep(3000);
- System.out.println("买好厨具");
- }catch (InterruptedException e){
- e.printStackTrace();
- }
- return true;
- }
- }
- 2)shicai
- public class shicai implements Callable<Boolean>{
- @Override
- public Boolean call() throws Exception {
- try{
- System.out.println("买食材");
- Thread.sleep(1000);
- System.out.println("买好食材");
- }catch(InterruptedException e){
- e.printStackTrace();
- }
- return true;
- }
- }
- 3)zuofan
- public class zuofan implements Callable<Boolean>{
- @Override
- public Boolean call() throws Exception {
- try{
- System.out.println("做饭");
- Thread.sleep(5000);
- System.out.println("做好饭");
- }catch (InterruptedException e){
- e.printStackTrace();
- }
- return true;
- }
- }
- 4)Main
- public class Main {
- public static void main(String[] args) {
- ExecutorService es = Executors.newCachedThreadPool();
- chuju cj = new chuju();
- shicai sc = new shicai();
- Future<Boolean> f1 = es.submit(cj);
- Future<Boolean> f2 = es.submit(sc);
- try{
- Boolean b1 = f1.get();// 会阻塞当前线程
- Boolean b2 = f2.get();
- System.out.println(b1);
- System.out.println(b2);
- if(b1 && b2){
- zuofan zf = new zuofan();
- es.submit(zf);
- }
- }catch(InterruptedException e){
- e.printStackTrace();
- }catch (ExecutionException e){
- e.printStackTrace();
- }
- es.shutdown();
- }
- }
5)执行结果
Connected to the target VM, address: '127.0.0.1:57304', transport: 'socket'
买厨具
买食材
买好食材
买好厨具
true
true
做饭
Disconnected from the target VM, address: '127.0.0.1:57304', transport: 'socket'
做好饭
Process finished with exit code 0
从运行结果可以看出, 买出具代码和买食材代码是异步执行的, 这两个都执行完毕后, 才执行的做饭代码. 那么为什么子线程 zuofan 没有先执行呢? 由于 Future 的 get()方法没有得到返回值, 让当前线程暂时挂起了.
注意: Future 的 get()方法, 如果拿不到结果会阻塞当前线程.
Java 线程池(Callable+Future 模式)
来源: http://www.bubuko.com/infodetail-2846960.html