`
247687009
  • 浏览: 173191 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

JAVA并行异步编程线程池+FutureTask

阅读更多

 

java 在JDK1.5中引入一个新的并发包java.util.concurrent 该包专门为java处理并发而书写。

在java中熟悉的使用多线程的方式为两种?继续Thread类,实现Runnale。两种方式简单方便。

在Jdk1.5之后其实有第三种方式实现方式,采用并发包中的Callable接口 FuruteTask类 以及ExecutorService接口。

 

说新的实现方式之前先来说讨论一下传统的java执行过程

 

首先一个简单的程序一个方法生成随机数,在生成随机数的方法执行中,睡眠1s模拟方法调用时候的耗时,把结果放进集合中,最后算到总结果。

public 
        class Count{
                public static void main(String[] args) throws InterruptedException {
                        long start = System.currentTimeMillis();
                       Count count = new Count();
                       List<Integer> res = new ArrayList<>();
                       res.add(count.random());
                       res.add(count.random());
                       res.add(count.random());
                       res.add(count.random());
                       int totle =0;
                       for (int i = 0; i < res.size(); i++) {
                               totle+=res.get(i);
                       }
                      long end = System.currentTimeMillis();
                       System.out.println("运算结束 耗时:"+(end-start)+"ms  totle:"+totle );
                       System.out.println("退出main线程!");
               }
                int random() throws InterruptedException{
                        Thread.sleep(1000); //
                        return new Random().nextInt(100);
                }
        }

    结果如下

运算结束 耗时:4000ms  totle:66
退出main线程!

     在传统的编写中是单线程的操作,串行操作,当调用方法count.random(),main线程被阻塞起来,直到睡眠时间到达,自动唤醒main线程。



 

那么有没有什么办法来减少main主线程的阻塞时间呢?能不能让这几个操作并行进行呢?如果是并行运行带来什么好处呢?

 

并行带来的好处,可以减少比较多的方法执行时间,如random()方法并行计算,也就是说main线程的阻塞只有1s,阻塞时间减少75%


 

java为我们提供了多线程机制,利用多线程我们可以实现方法的并行运算,实现多线程的办法,实现Runnable接口重新run,继承Thread 重写run;因为run方法的并没有返回值,我们手动的去创建大量的线程并且维护线程是件很讨厌的事情,并且创建线程也是非常耗费资源的操作,能不能有一个池子来帮我们管理线程呢?有没有一个类能够透明的去进行透明并发的异步操作呢?这个在JDK1.5之前是没有的,在1,5之后出现了一个新包,专门为并发而开发的包,使用并发包中提供的类和接口,将很轻易的实现。并发编程。

import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.FutureTask;

 public class TestMain {
        public static void main(String[] args) throws InterruptedException, ExecutionException {
                new  TestMain().exec();
        }
        void exec() throws InterruptedException, ExecutionException{
                //进行异步任务列表
                List<FutureTask<Integer>> futureTasks = new ArrayList<FutureTask<Integer>>();
                //线程池 初始化十个线程 和JDBC连接池是一个意思 实现重用 
                ExecutorService executorService = Executors.newFixedThreadPool(10);
                long start = System.currentTimeMillis();
                //类似与run方法的实现 Callable是一个接口,在call中手写逻辑代码
                Callable<Integer> callable = new Callable<Integer>() {
                        @Override
                        public Integer call() throws Exception {
                                Integer res = new Random().nextInt(100);
                                Thread.sleep(1000);
                                System.out.println("任务执行:获取到结果 :"+res);
                                return  res;
                        }
                };
                
                for(int i=0;i<10;i++){
                        //创建一个异步任务
                        FutureTask<Integer> futureTask = new FutureTask<Integer>(callable);
                        futureTasks.add(futureTask);
                        //提交异步任务到线程池,让线程池管理任务 特爽把。
                               //由于是异步并行任务,所以这里并不会阻塞
                        executorService.submit(futureTask); 
                }
                
                int count = 0;
             for (FutureTask<Integer> futureTask : futureTasks) {
                     //futureTask.get() 得到我们想要的结果 
                     //该方法有一个重载get(long timeout, TimeUnit unit) 第一个参数为最大等待时间,第二个为时间的单位
                     count+= futureTask.get();
        }
           long end = System.currentTimeMillis();
           System.out.println("线程池的任务全部完成:结果为:"+count+",main线程关闭,进行线程的清理");
           System.out.println("使用时间:"+(end-start)+"ms");
           //清理线程池 
           executorService.shutdown();
                
        }
}

 上述情况如果不用异步并行,程序将至少睡眠10s

 使用之后的结果

任务执行:获取到结果 :99
任务执行:获取到结果 :78
任务执行:获取到结果 :52
任务执行:获取到结果 :78
任务执行:获取到结果 :97
任务执行:获取到结果 :8
任务执行:获取到结果 :97
任务执行:获取到结果 :3
任务执行:获取到结果 :78
任务执行:获取到结果 :31
线程池的任务全部完成:结果为:621,main线程关闭,进行线程的清理
使用时间:1004ms 

   我们试着把线程池的大小减少一半

  

任务执行:获取到结果 :87
任务执行:获取到结果 :60
任务执行:获取到结果 :13
任务执行:获取到结果 :18
任务执行:获取到结果 :8
任务执行:获取到结果 :86
任务执行:获取到结果 :52
任务执行:获取到结果 :4
任务执行:获取到结果 :23
任务执行:获取到结果 :16
线程池的任务全部完成:结果为:367,main线程关闭,进行线程的清理
使用时间:2017ms

   好玩吧 时间延长了一半。

 

 

  • 大小: 19.5 KB
  • 大小: 11.4 KB
2
0
分享到:
评论

相关推荐

    java_util_concurrent中文版pdf

    7. **CompletableFuture**:Java 8引入的CompletableFuture是异步编程的新工具,它允许对未来的计算结果进行链式操作,支持组合多个异步操作,简化了复杂的回调处理。 8. **线程局部变量**:ThreadLocal为每个线程...

    并发容器和线程池,java并发编程3

    `CompletableFuture`是一个更加高级的异步编程模型,它结合了`Future`和`Promise`的思想,提供了更强大的功能,如组合多个异步任务、执行链式调用等。 **特点**: - **链式调用**:支持异步任务的链式调用,简化...

    java实现线程的异步

    Java 8 引入了 CompletableFuture,提供了强大的异步编程工具。它可以用于构建复杂的异步操作链,并且支持链式调用: ```java CompletableFuture.supplyAsync(() -&gt; { // 异步操作 return "Hello"; }).thenApply...

    并发编程笔记+包含所有

    在IT行业中,尤其是在Java开发领域,并发编程是不可或缺的一个重要环节。这门技术涉及如何让多个任务在同一时间执行,以提高程序的效率和系统资源的利用率。本笔记主要聚焦于Java平台上的并发编程,旨在帮助开发者...

    java多线程异步性

    Java多线程异步性是Java编程中一个关键的概念,特别是在设计高性能、高并发的应用时。多线程允许程序同时执行多个独立的任务,而异步性则是这些任务在不互相等待的情况下并行运行的能力,提高了系统的效率和响应速度...

    JAVA并发编程实践

    - **FutureTask**:用于表示异步计算的结果,可以等待计算完成并获取结果。 - **CountDownLatch**:用于控制线程等待其他线程完成某些操作。 - **CyclicBarrier**:让一组线程等待到达某个公共屏障点。 #### 1.3 ...

    Java并发编程实战

    1.2.3 异步事件的简化处理 1.2.4 响应更灵敏的用户界面 1.3 线程带来的风险 1.3.1 安全性问题 1.3.2 活跃性问题 1.3.3 性能问题 1.4 线程无处不在 第一部分 基础知识 第2章 线程安全性 2.1 什么是线程安全...

    JAVA并发编程实践.pdf

    根据提供的信息,“JAVA并发编程实践.pdf”这一文档主要聚焦于Java并发编程的实践与应用,这对于希望深入了解并行处理和多线程技术的开发者来说是非常有价值的资源。下面将基于标题和描述中的关键词“JAVA并发编程...

    《Java并发编程实战》PDF版本下载.txt

    根据提供的文件信息,我们可以推断出这是一份关于获取《Java并发编程实战》PDF版本的资源分享。然而,为了满足您对于生成相关知识点的需求,我们将围绕《Java并发编程实战》这本书的内容来展开讨论,深入解析Java...

    JAVA并发编程实践 中文 高清 带书签 完整版 Doug Lea .pdf

    - **FutureTask**:实现了RunnableFuture接口,用于包装异步计算的结果。 - **Callable接口**:与Runnable类似,但可以返回结果,并抛出异常。 #### 4.2 生产者-消费者模式 - **BlockingQueue**:阻塞队列,是实现...

    Java 并发编程实战

    1.2.3 异步事件的简化处理 1.2.4 响应更灵敏的用户界面 1.3 线程带来的风险 1.3.1 安全性问题 1.3.2 活跃性问题 1.3.3 性能问题 1.4 线程无处不在 第一部分 基础知识 第2章 线程安全性 2.1 什么是线程安全...

    android线程池案例

    线程池是一种机制,它允许多个任务在后台并行执行,从而避免频繁创建和销毁线程带来的开销。"android线程池案例"提供了这样的示例,用于演示如何在Android应用程序中有效地使用线程池,并结合进度条来显示任务的执行...

    Java并发编程

    Java提供了丰富的工具和API来支持并发编程,如线程(Thread)、守护线程(Daemon Thread)、线程池(Executor Service)等。 Java中的线程是并发的基础,通过创建Thread对象或实现Runnable接口可以创建新的线程。...

    Java并发编程原理与实战

    Spring对并发的支持:Spring的异步任务.mp4 使用jdk8提供的lambda进行并行计算.mp4 了解多线程所带来的安全风险.mp4 从线程的优先级看饥饿问题.mp4 从Java字节码的角度看线程安全性问题.mp4 synchronized保证线程...

    Java并发编程实战(中文版带详细目录).pdf

    - **异步编程**:通过Future接口获取计算结果,无需等待任务执行完毕。 - **FutureTask**:实现了Runnable和Future两个接口,可以将Callable和Runnable包装成FutureTask。 **3.2 CompletableFuture** - **组合操作...

    ExcutorUtil:线程池 异步同步任务

    在Java编程语言中,线程池(ThreadPool)是并发处理中的一个重要概念,它通过复用已存在的线程来提高程序的执行效率。...对线程池和异步编程的深入理解是Java并发编程的关键,对于提升软件的性能和可扩展性至关重要。

    JAVA-multithreaded-programming.rar_Java @multithreaded_java prog

    - **FutureTask**:表示异步计算的结果,可以检查计算是否完成,获取或取消计算结果。 9. **实例应用** - **Web服务器**:多线程处理HTTP请求。 - **数据库连接池**:线程池管理数据库连接。 - **文件读写**:...

    Java并发编程(学习笔记).xmind

    Java并发编程 背景介绍 并发历史 必要性 进程 资源分配的最小单位 线程 CPU调度的最小单位 线程的优势 (1)如果设计正确,多线程程序可以通过提高处理器资源的利用率来提升系统吞吐率 ...

Global site tag (gtag.js) - Google Analytics