JAVA并行异步编程,线程池+FutureTask(分享来自推酷)
来源:互联网 发布:白苹果刷机数据恢复 编辑:程序博客网 时间:2024/05/29 16:11
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
好玩吧 时间延长了一半。
- JAVA并行异步编程,线程池+FutureTask(分享来自推酷)
- JAVA并行异步编程线程池+FutureTask
- JAVA并行异步编程线程池+FutureTask
- JAVA并行异步编程线程池+FutureTask
- JAVA并行异步编程,线程池+FutureTask+callable+ExecutorService
- Java 异步线程FutureTask的使用和SwingWorker
- Java 线程池 Executor框架(2)FutureTask
- Java线程池——FutureTask
- Java线程之FutureTask
- java线程之FutureTask
- Java线程之FutureTask
- Java线程之FutureTask
- Java并发编程线程中:Callable、Future和FutureTask类
- 异步,线程,并行概念
- Java线程池之FutureTask【Java线程池系列3】
- futureTask和线程池
- java线程创建之FutureTask
- 关于java线程池的研究-Future与FutureTask
- 大话操作系统(1)基本概念
- 开放API(OpenAPI)
- JAVA设计模式之:模板方法模式
- Android5.0风格EditText输入框效果
- linux grep命令
- JAVA并行异步编程,线程池+FutureTask(分享来自推酷)
- android:layout_weight设置解读
- Bonfire: Where art thou
- 一份不可多得的健身房健身计划
- solr教程,值得刚接触搜索开发人员一看
- hibernate-annotation注解解释
- ajax标准方法
- AngularJS 03
- 【web前端攻城狮】表单验证之电话验证