zoukankan      html  css  js  c++  java
  • Java线程池(Callable+Future模式)

    转:

    Java线程池(Callable+Future模式)

    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()方法,如果拿不到结果会阻塞当前线程。
  • 相关阅读:
    尚观寻求帮助
    linux软链接与硬连接
    linux常用命令(三)
    zend 动作控制器
    zend 路由
    ZF组件功能简介
    zend_controller
    linux常用命令(一)
    练习1
    练习1感受:
  • 原文地址:https://www.cnblogs.com/libin6505/p/11250405.html
Copyright © 2011-2022 走看看