Java 多线程执行

Wesley13
• 阅读 558

背景:

如果一个任务由多个子任务组成,子任务全部执行完成后然后由主线程对所有子任务结果进行封装,可以采用如下几种方式:

1、基于Guava ListenableFuture 进行;

2、基于FutureTask 和CountDownLatch进行

3、基于FutureTask进行;

4、基于CompletionService进行

5、基于BlockingQueue进行

说明:

2、3 的区别就是线程池时候每次都新建、shutdown;

4、5 是一个东西

public static void listenableFuture() {
        try {
            ListeningExecutorService pool = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors() * 2));
            List<ListenableFuture<Integer>> futures = new ArrayList<>();
            for (int i = 0; i < 20; i++) {
                final ListenableFuture<Integer> future = pool.submit(new CountTask());
                futures.add(future);
                Futures.addCallback(future, new FutureCallback<Integer>() {
                    @Override
                    public void onSuccess(Integer result) {
                        System.out.println(result);
                    }

                    @Override
                    public void onFailure(Throwable t) {
                        t.printStackTrace();
                    }
                });
            }
            System.out.println("submit success");
            ListenableFuture<List<Integer>> ret = Futures.successfulAsList(futures);
            List<Integer> res = ret.get();
            System.out.println(res);
            pool.shutdown();
            System.out.println("shutdown success");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void countDownCount() throws Exception {
        int threadNum = 20;
        ExecutorService executor = Executors.newCachedThreadPool();
        CountDownLatch count = new CountDownLatch(threadNum);
        List<FutureTask<Integer>> futureTasks = new ArrayList<>();
        for (int i = 0; i < threadNum; i++) {
            CountTask task = new CountTask(count);
            FutureTask<Integer> futureTask = new FutureTask<>(task);
            executor.submit(futureTask);
            futureTasks.add(futureTask);
        }
        // 该动作会阻塞主线程知道各个线程完成任务
        count.await();
        System.out.println("执行完成");
        for (FutureTask<Integer> futureTask : futureTasks) {
            Integer ret = futureTask.get();
            System.out.println(ret);
        }
        executor.shutdown();
        System.out.println("测试完成");
    }

    public static void futureTaskCount() throws Exception {
        int threadNum = 20;
        ExecutorService executor = Executors.newCachedThreadPool();
        List<FutureTask<Integer>> futureTasks = new ArrayList<>();
        for (int i = 0; i < threadNum; i++) {
            CountTask task = new CountTask();
            FutureTask<Integer> futureTask = new FutureTask<>(task);
            executor.submit(futureTask);
            futureTasks.add(futureTask);
        }
        // 关闭线程池,该动作会阻塞主线程知道线程池中线程执行完成
        executor.shutdown();
        System.out.println("shutdown");
        for (FutureTask<Integer> futureTask : futureTasks) {
            Integer ret = futureTask.get();
            System.out.println(ret);
        }
        System.out.println("测试完成");
    }

    public static void completionCount() throws Exception {
        int threadNum = 20;
        ExecutorService executor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors() * 2);
        CompletionService<Integer> pool = new ExecutorCompletionService<Integer>(executor);
        for (int i = 0; i < threadNum; i++) {
            pool.submit(new CountTask());
        }
        for (int i = 0; i < threadNum; i++) {
            Integer ret = pool.take().get();
            System.out.println("输出结果" + ret);
        }
        System.out.println("测试完成");
        executor.shutdown();
    }

    // 使用阻塞容器保存每次Executor处理的结果,在后面进行统一处理
    public static void blockingQueueCount() throws Exception {
        ExecutorService exec = Executors.newCachedThreadPool();
        BlockingQueue<Future<Integer>> queue = new LinkedBlockingQueue<Future<Integer>>();
        for (int i = 0; i < 10; i++) {
            Future<Integer> future = exec.submit(new CountTask());
            queue.add(future);
        }
        int sum = 0;
        int queueSize = queue.size();
        for (int i = 0; i < queueSize; i++) {
            sum += queue.take().get();
        }
        System.out.println("总数为:" + sum);
        exec.shutdown();
    }
点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
待兔 待兔
3个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Stella981 Stella981
3年前
Opencv中Mat矩阵相乘——点乘、dot、mul运算详解
Opencv中Mat矩阵相乘——点乘、dot、mul运算详解2016年09月02日00:00:36 \牧野(https://www.oschina.net/action/GoToLink?urlhttps%3A%2F%2Fme.csdn.net%2Fdcrmg) 阅读数:59593
Stella981 Stella981
3年前
Nginx + lua +[memcached,redis]
精品案例1、Nginxluamemcached,redis实现网站灰度发布2、分库分表/基于Leaf组件实现的全球唯一ID(非UUID)3、Redis独立数据监控,实现订单超时操作/MQ死信操作SelectPollEpollReactor模型4、分布式任务调试Quartz应用
Stella981 Stella981
3年前
KVM调整cpu和内存
一.修改kvm虚拟机的配置1、virsheditcentos7找到“memory”和“vcpu”标签,将<namecentos7</name<uuid2220a6d1a36a4fbb8523e078b3dfe795</uuid
Stella981 Stella981
3年前
Android So动态加载 优雅实现与原理分析
背景:漫品Android客户端集成适配转换功能(基于目标识别(So库35M)和人脸识别库(5M)),导致apk体积50M左右,为优化客户端体验,决定实现So文件动态加载.!(https://oscimg.oschina.net/oscnet/00d1ff90e4b34869664fef59e3ec3fdd20b.png)点击上方“蓝字”关注我
Easter79 Easter79
3年前
Twitter的分布式自增ID算法snowflake (Java版)
概述分布式系统中,有一些需要使用全局唯一ID的场景,这种时候为了防止ID冲突可以使用36位的UUID,但是UUID有一些缺点,首先他相对比较长,另外UUID一般是无序的。有些时候我们希望能使用一种简单一些的ID,并且希望ID能够按照时间有序生成。而twitter的snowflake解决了这种需求,最初Twitter把存储系统从MySQL迁移
Wesley13 Wesley13
3年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Java服务总在半夜挂,背后的真相竟然是... | 京东云技术团队
最近有用户反馈测试环境Java服务总在凌晨00:00左右挂掉,用户反馈Java服务没有定时任务,也没有流量突增的情况,Jvm配置也合理,莫名其妙就挂了