大家好,我是烤鸭:

今天说一下 多线程的几种创建方式及使用。

1. Thread 和 Runnable

继承 Thread 类 和实现 Runnable 接口。
    这种就不举例子了。

2.线程池

现在主要有5种线程池。

  //缓存线程池ExecutorService cachedThreadPool = Executors.newCachedThreadPool(); //固定大小线程池ExecutorService fixedThreadPool = Executors.newFixedThreadPool(10);//单线程执行ExecutorService singleThreadPool = Executors.newSingleThreadExecutor();//定时或延迟执行ExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(10);//窃取线程池ExecutorService workStealingPool = Executors.newWorkStealingPool();

其中 newWorkStealingPool 是jdk 1.8以后新出的,为了防止线程池启用过多,导致cpu占用过多导致的项目宕机。适用于执行多任务,且每个任务耗时时间较短。
  其余4种方式都有可能会出现占用cpu过高导致的项目宕机的情况。
  以 4核 16G的机器为例, Executors.newFixedThreadPool(10) 这种方式创建的线程池大小为10
  Executors.newWorkStealingPool() 创建线程池大小为4。一般来说,和核数相等
  即便不使用这种方式,也建议不要超过 核数 * 2。(具体看需求)

3. Future和CompletableFuture

Future 是 jdk1.5 以后出现的,用于异步多线程。
例子:

// 创建Future集合,用于存放完成的Future
List<Future<Long>> futureList = new ArrayList();
//多线程执行任务
for (int i = 0; i < 100; i++) {Future<Long> testFuture= workStealingPool.submit(new Callable<Long>() {@Overridepublic Long call() {//模拟执行耗时任务System.out.println("task 1 doing...");try {Thread.sleep(1000);} catch (Exception e) {e.printStackTrace();}return 0L;}});futureList.add(testFuture);
}
//遍历list,获取线程结果
for (Future<Long> taskResponseFuture: futureList) {if(taskResponseFuture.get().equals(0L)){//当前future执行完毕}
}

这里注意一下,Future.get()是阻塞方法。如果需要多线程执行操作,在最后的时候执行get()方法。
类似上边的例子,可以把 多个 Future 放到list中,再循环get。

CompletableFuture 是 Future的实现类,关于异步多线程提供了更多的api,下面介绍几种常用的。

supplyAsync 异步执行,有返回值

CompletableFuture<Integer> completableFuture1 = CompletableFuture.supplyAsync(() -> {//模拟执行耗时任务System.out.println("task 1 doing...");try {Thread.sleep(1000);} catch (Exception e) {e.printStackTrace();}//返回结果return 0;
});

thenAccept 接收上一阶段的输出作为本阶段的输入。多线程(单个线程)的顺序执行。

completableFuture1.thenApply(new Function<Integer, Object>() {@Overridepublic Object apply(Integer integer) {//模拟执行耗时任务System.out.println("task thenApply doing...");try {Thread.sleep(1000);} catch (Exception e) {e.printStackTrace();}return 0;}
});

whenComplete 异步监听结果

completableFuture1.whenComplete(new BiConsumer<Integer,Throwable>() {@Overridepublic void accept(Integer o, Throwable o2) {if(o == 0L){System.out.println("task complete...");}else{throw new RuntimeException();}}
});

多线程创建方式 线程池、Future和CompletableFuture相关推荐

  1. java多线程创建runnable_Java线程池和runnables创建runnables

    有很多方法可以做你想要的 . 您需要小心,不要最终创建太多线程 . 以下是一个示例,您可以使用ExecutorCompletionService提高效率,也可以使用Runnable . import ...

  2. Python3进阶--Socket编程、多线程(创建方式、线程通信、线程锁、线程池)

    第一章 变量.常用循环体.代码结构.代码练习 第二章 列表.元组等数据结构.字符串驻留机制及字符串格式化操作 第三章 函数.面向对象.文件操作.深浅拷贝.模块.异常及捕获 第四章 项目打包.类和对象高 ...

  3. 26_多线程_第26天(Thread、线程创建、线程池)_讲义

    今日内容介绍 1.多线程 2.线程池 01进程概念 A:进程概念 a:进程:进程指正在运行的程序.确切的来说,当一个程序进入内存运行, 即变成一个进程,进程是处于运行过程中的程序,并且具有一定独立功能 ...

  4. 26_多线程_第26天(Thread、线程创建、线程池)

    今日内容介绍 1.多线程 2.线程池 01进程概念 A:进程概念 a:进程:进程指正在运行的程序.确切的来说,当一个程序进入内存运行, 即变成一个进程,进程是处于运行过程中的程序,并且具有一定独立功能 ...

  5. Java多线程系列--“JUC线程池”06之 Callable和Future

    转载自  Java多线程系列--"JUC线程池"06之 Callable和Future Callable 和 Future 简介 Callable 和 Future 是比较有趣的一 ...

  6. Java多线程系列 JUC线程池01 线程池框架

    转载  http://www.cnblogs.com/skywang12345/p/3509903.html 为什么引入Executor线程池框架 new Thread()的缺点 1. 每次new T ...

  7. java多线程编程之线程池技术全面解读

    在多线程编程时,创建线程是十分消耗资源的,当线程创建过多时,便会引发内存溢出,因此引入了线程池技术. 目录 线程池的优势 线程池的创建&使用 线程池的工作原理 线程池的参数 功能线程池 线程池 ...

  8. ExecutorService为创建的线程池ExecutorService pool = Executors.newFixedThreadPool(POOL_SIZE)

    ExecutorService就是要创建的线程池  JAVA中线程池用类ExecutorService代表 ,案例ExecutorService pool = Executors.newFixedTh ...

  9. Java多线程系列 JUC线程池05 线程池原理解析(四)

    转载 http://www.cnblogs.com/skywang12345/p/3544116.html  https://blog.csdn.net/programmer_at/article/d ...

最新文章

  1. V3S拍照上传又拍云bug排查过程
  2. python爬虫如何连接数据库_手把手教你如何在Navicat中如何新建连接数据库及相关报错解决方法...
  3. 判别器loss为0_TensorFlow v2.0实现逻辑斯谛回归
  4. 会计用计算机很快是,40个超实用电脑快捷键,老会计都在用
  5. leetcode 1178. 猜字谜(位运算)
  6. Java魔法堂:初探MessageFormat.format和ChoiceFormat
  7. Mate 50系列首发?曝鸿蒙3.0用户版5月内测
  8. 报表中表达式的全局集合(Visual Studio 报表设计器)
  9. ASP.NET Core搭建多层网站架构【11-WebApi统一处理返回值、异常】
  10. python学习总结----异常处理
  11. 20191208_神经网络交叉验证
  12. dell服务器管理口ip地址_戴尔服务器IDRAC命令配置IP地址
  13. 计算机通讯端口怎么增加,plc通讯接口如何添加删除方法
  14. U8常用的二次开发方式
  15. 【10大基础算法】线性查找算法-NO5
  16. 《预训练周刊》第52期:屏蔽视觉预训练、目标导向对话
  17. 服务器flash卡的作用是什么原因,直播卡顿原因详解及优化
  18. 一期Go群问答-并发控制-数据竞争-错误与异常
  19. SpringBoot启动图标修改(通俗易懂)
  20. Layui hint: is not a valid module

热门文章

  1. [vue] v-model是什么?有什么用呢?
  2. [css] 如何使用css3实现一个div设置多张背景图片?
  3. [css] 为什么说不提倡用1px的小尺寸图片做背景平铺?
  4. 前端学习(2694):重读vue电商网站15之阻止页签tabs切换
  5. 工作190:页面数据不显示
  6. “约见”面试官系列之常见面试题之第八十篇之css常见属性(建议收藏)
  7. 前端学习(1679):前端系列实战课程之为蛇创建食物对象
  8. 前端学习(294):rem小实例
  9. shiro学习(22):动态添加验证规则2
  10. 第一百三十六期:详细讲解 Redis 的两种安装部署方式