多线程与高并发(七):详解线程池 - 自定义线程池,JDK自带线程池,ForkJoin,源码解析等
Executor 接口关系
Callable:类似于Runnable,但是可以有返回值
Future:存储将来执行的结果。Callable被执行完之后的结果,被封装到Future里面。
Future 示例:
/*** 认识Callable,对Runnable进行了扩展* 对Callable的调用,可以有返回值*/
package com.mashibing.juc.c_026_01_ThreadPool;import java.util.concurrent.*;public class T03_Callable {public static void main(String[] args) throws ExecutionException, InterruptedException {Callable<String> c = new Callable() {@Overridepublic String call() throws Exception {return "Hello Callable";}};ExecutorService service = Executors.newCachedThreadPool();Future<String> future = service.submit(c); //异步System.out.println(future.get());//阻塞service.shutdown();}
}
FutureTask:更加灵活,是Runnable和Future的结合,既是一个Runnable,又可以存结果
FutureTask示例:
/*** 认识FutureTask*/
package com.mashibing.juc.c_026_01_ThreadPool;import java.util.concurrent.*;public class T06_00_Future {public static void main(String[] args) throws InterruptedException, ExecutionException {FutureTask<Integer> task = new FutureTask<>(() -> {TimeUnit.MILLISECONDS.sleep(500);return 1000;}); //new Callable () { Integer call();}new Thread(task).start();System.out.println(task.get()); //阻塞}
}
CompletableFuture
可以用来管理多个Future的结果,对各种各样的结果进行组合处理。你可以去查查它的API~
提供了很多非常好用的接口,十分友好!
示例:假设你能够提供一个服务,这个服务查询各大电商网站同一类产品的价格并汇总展示,你用CompletableFuture开启三个线程来完成这个任务
package com.mashibing.juc.c_026_01_ThreadPool;import java.io.IOException;
import java.util.Random;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;public class T06_01_CompletableFuture {public static void main(String[] args) throws ExecutionException, InterruptedException {long start, end;/*start = System.currentTimeMillis();priceOfTM();priceOfTB();priceOfJD();end = System.currentTimeMillis();System.out.println("use serial method call! " + (end - start));*/start = System.currentTimeMillis();CompletableFuture<Double> futureTM = CompletableFuture.supplyAsync(() -> priceOfTM());CompletableFuture<Double> futureTB = CompletableFuture.supplyAsync(() -> priceOfTB());CompletableFuture<Double> futureJD = CompletableFuture.supplyAsync(() -> priceOfJD());CompletableFuture.allOf(futureTM, futureTB, futureJD).join(); // 提供对于一堆任务的管理:这三个任务全部完成之后,才能继续向下运行
// CompletableFuture.anyOf(futureTM, futureTB, futureJD).join(); // 任意一个任务完成,就能继续向下运行CompletableFuture.supplyAsync(() -> priceOfTM()).thenApply(String::valueOf).thenApply(str -> "price " + str).thenAccept(System.out::println);end = System.currentTimeMillis();System.out.println("use completable future! " + (end - start));try {System.in.read();//因为里面全是异步,所以需要阻塞一下,才能正常的等待它们输出,不然主线程先结束了。。} catch (IOException e) {e.printStackTrace();}}private static double priceOfTM() {delay();return 1.00;}private static double priceOfTB() {delay();return 2.00;}private static double priceOfJD() {delay();return 3.00;}/*private static double priceOfAmazon() {delay();throw new RuntimeException("product not exist!");}*/private static void delay() {int time = new Random().nextInt(500);try {TimeUnit.MILLISECONDS.sleep(time);} catch (InterruptedException e) {e.printStackTrace();}System.out.printf("After random %s sleep!\n", time);}
}
线程池
ThreadPoolExecutor:我们通常所说的线程池
ForkJoinPoll:先将任务分解,最后再汇总
如何自定义一个线程池
阿里《Java开发手册》建议自定义线程池,所以我们先来看看如何自定义一个线程池。
线程池
维护两个集合:
- 线程集合
- 任务集合
用的是HashSet
定义一个自定义线程池,最多有7个参数,这个面试经常被使劲问
package com.mashibing.juc.c_026_01_ThreadPool;import java.io.IOException;
import java.util.concurrent.*;public class T05_00_HelloThreadPool {static class Task implements Runnable {private int i;public Task(int i) {this.i = i;}@Overridepublic void run() {System.out.println(Thread.currentThread().getName() + " Task " + i);try {System.in.read();} catch (IOException e) {e.printStackTrace();}}@Overridepublic String toString() {return "Task{" +"i=" + i +'}';}}public static void main(String[] args) {ThreadPoolExecutor tpe = new ThreadPoolExecutor(2, 4,60, TimeUnit.SECONDS,new ArrayBlockingQueue<Runnable>(4),Executors.defaultThreadFactory(),new ThreadPoolExecutor.CallerRunsPolicy());for (int i = 0; i < 8; i++) {tpe.execute(new Task(i));}System.out.println(tpe.getQueue());tpe.execute(new Task(100));System.out.println(tpe.getQueue());tpe.shutdown();}
}
多线程与高并发(七):详解线程池 - 自定义线程池,JDK自带线程池,ForkJoin,源码解析等相关推荐
- Java高并发编程详解系列-Java线程入门
根据自己学的知识加上从各个网站上收集的资料分享一下关于java高并发编程的知识点.对于代码示例会以Maven工程的形式分享到个人的GitHub上面. 首先介绍一下这个系列的东西是什么,这个系列自己 ...
- 从根上理解高性能、高并发(七):深入操作系统,一文读懂进程、线程、协程
本文引用了"一文读懂什么是进程.线程.协程"一文的主要内容,感谢原作者的无私分享. 1.系列文章引言 1.1 文章目的 作为即时通讯技术的开发者来说,高性能.高并发相关的技术概念早 ...
- 多线程与高并发(六):线程池可用的各种高并发容器详解:CopyOnWriteList,BlockingQueue等
容器 物理结构:数组.链表 逻辑结构:很多 Queue主要是为高并发准备的. Vector Hashtable Vector Hashtable 自带锁,有很多设计上不完善的地方,现在基本上不用. 测 ...
- Java高并发编程详解系列-线程上下文设计模式及ThreadLocal详解
导语 在之前的分享中提到过一个概念就是线程之间的通信,都知道在线程之间的通信是一件很消耗资源的事情.但是又不得不去做的一件事情.为了保证多线程线程安全就必须进行线程之间的通信,保证每个线程获取到的 ...
- Java高并发编程详解系列-线程通信
进程间的通信,又被称为是进程内部的通信,我们都知道每个进程中有多个线程在执行,多个线程要互斥的访问共享资源的时候会发送对应的等待信号或者是唤醒线程执行等信号.那么这些信号背后还有什么样的技术支持呢 ...
- Java高并发编程详解系列-线程池原理自定义线程池
之前博客的所有内容是对单个线程的操作,例如有Thread和Runnable的使用以及ThreadGroup等的使用,但是对于在有些场景下我们需要管理很多的线程,而对于这些线程的管理有一个统一的管理工具 ...
- Java高并发编程详解系列-线程安全数据同步
在多线程中最为复杂和最为重要的就是线程安全.多个线程访问同一个对象的时候会导致线程安全问题.通过加锁可以避免这种问题.但是在串行执行的过程中又不用考虑线程安全问题,而使用串行程序效率低没有办法将CPU ...
- Java高并发编程详解系列-线程上下文类加载
前面的分享中提到的最多的概念就是关于类加载器的概念,但是当我们查看Thread源码的时候会发现如下的两个方法,这两个方法就是获取或者设置线程的上下文类加载器的方法,那么为什么要设置这两个方法呢?这个就 ...
- Java高并发编程详解系列-线程异常处理
前面的博客中主要描述的关于线程的概念,通过源码分析了解线程的基本操作方式,但是如何在线程运行期间获取异常信息呢?这就要使用到一个Hook线程了 线程运行时的异常 在Thread类中,关于线程运行时 ...
- Java高并发编程详解系列-7种单例模式
引言 在之前的文章中从技术以及源代码的层面上分析了关于Java高并发的解决方式.这篇博客主要介绍关于单例设计模式.关于单例设计模式大家应该不会陌生,作为GoF23中设计模式中最为基础的设计模式,实现起 ...
最新文章
- 线性模型已退场,XGBoost时代早已来
- Hive代码组织及架构简单介绍
- 计算机知识必备,小结||计算机基础知识点十(必备)
- ElasticSearch各种查询对象Query的使用
- 关于本Blog无法进行评论问题的说明
- eclipse打包jar发布到linux下运行出错(java.lang.ClassNotFoundException: cmd.WordCount$MyMapper )
- MySql的连接查询
- Java设计模式、框架、架构、平台之间的关系
- 前端组件化和模块化最大的区别是什么_7招提升你的前端开发效率
- EIGRP路由协议的简单理解及应用
- tesseract如何在Linux下卸载,Tesseract装配
- java duplicate key_java.lang.IllegalStateException: Duplicate key 1
- 【初识Unity】UI游戏:看看你能答对几题?(游戏可下载)
- 老主板怎么接机箱前面的USB和mic
- 杰理之实现蓝牙三方通话功能【篇】
- win7 64位 SEC S3C2410X Test B/D安装
- mac 时间机器备份到windows共享文件遇到的问题及解决记录
- Vue 组件事件触发另一个组件的事件
- 计算机的论文的引言,计算机类论文中引言的写法分析.pdf
- 全年销售完成目标,远洋集团的根本问题却仍未解决