java Runnable、Callable、FutureTask 和线程池
一:Runnable、Callable、FutureTask简介
(1)Runnable:其中的run()方法没有返回值。
①.Runnable对象可以直接扔给Thread创建线程实例,并且创建的线程实例与Runnable绑定,线程实例调用start()方法时,Runnable任务就开始真正在线程中执行。
②.Runnable对象也可以直接扔给线程池对象的execute方法和submit方法,让线程池为其绑定池中的线程来执行。
③.Runnable对象也可以进一步封装成FutureTask对象之后再扔给线程池的execute方法和submit方法。
(2)Callable:功能相比Runnable来说少很多,不能用来创建线程,也不能直接扔给线程池的execute方法,但是可以使用submit。其中的call方法有返回值,也进一步封装成Future,再由线程执行。
(3)FutureTask:是对Runnable和Callable的进一步封装,并且这种任务是有返回值的,它的返回值存在FutureTask类的一个名叫outcome的数据成员中。(疑惑)那么为什么可以把没有返回值的Runnable也封装成FutureTask呢,马上我们会讨论这个问题。相比直接把Runnable和Callable扔给线程池,FutureTask的功能更多,它可以监视任务在池子中的状态。用Runnable和Callable创建FutureTask的方法稍有不同。
(4)Runable 转换 Callable
Callable<Object> callable = Executors.callable(new MyRunnable());
(5)FutureTask 的使用
FutureTask futureTask = new FutureTask(new CallableTask());
new Thread(futureTask).start();//或者由线程池执行
FutureTask类实现了RunnableFuture接口,而RunnableFuture接口又继承了Runnable接口和Future接口,所以FutureTask类本质上是Runnable接口的实现类,且兼具Future接口的特性,我们知道线程池的execute方法和submit方法都可以执行Runable任务,所以同样可以执行FutureTask任务。
//FutureTask 构造函数
public FutureTask(Callable<V> callable);
public FutureTask(Runnable runnable, V result);
FutureTask类有一个done方法,该方法在任务执行完毕时自动回调,我们可以重写该方法并在该方法中调用get()方法获取任务执行的结果,并且因为任务已经执行完毕,此时调用get()方法可以直接得到结果,所以并不会阻塞线程。
二:线程池
(1)Executor 接口 只提供一个void execute(Runnable command),只能执行Runnable 任务,但是不能执行Callable 任务。所以提供了ExecutorService 接口。
(2)ExecutorService 接口 其继承了Executor,提供了submit()方法重载可以执行Runnable 任务和Callable任务。ExecutorService 可以创建四种线程池
①newSingleThreadExecutor 创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。
ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor(); //返回ExecutorService
singleThreadExecutor .submit() //可以是Runable任务或者Callable任务
②newFixedThreadPool 创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。
ExecutorService fixedThreadPool = Executors.newFixedThreadPool(3); //返回ExecutorService
fixedThreadPool .submit();//可以是Runable任务或者Callable任务
③newCachedThreadPool创建一个可缓存线程池,如果处理需求超过线程池长度,可灵活回收空闲线程,若无可回收,则新建线程,线程池无限大,举例:要执行两个人,如果在第二个任务执行前,第一个任务已经完成,则会复用第一个线程去执行第二个任务,不创建新的线程。
ExecutorService cachedThreadPool = Executors.newCachedThreadPool(); //返回ExecutorService
cachedThreadPool.submit();// 可以是Runable任务或者Callable任务
**④newScheduledThreadPool **创建一个定长线程池,支持定时及周期性任务执行。
ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(5); //返回ScheduledExecutorService 其继承了ExecutorService
scheduledThreadPool .scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit);
/*
ScheduledExecutorService接口 主要有以下方法,由ScheduledThreadPoolExecutor实现
1,<V> ScheduledFuture<V> schedule(Callable<V> callable, long delay, TimeUnit unit) //执行Callable
2,ScheduledFuture<?> schedule(Runnable command, long delay, TimeUnit unit) //执行Runable
3,ScheduledFuture<?> scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit) //以任务执行开始时间为起点,过多久执行一次
4,ScheduledFuture<?> scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit) //以任务执行结束时间为起点,过多久执行一次
*/
java Runnable、Callable、FutureTask 和线程池的更多相关文章
- java多线程系列六、线程池
一. 线程池简介 1. 线程池的概念: 线程池就是首先创建一些线程,它们的集合称为线程池. 2. 使用线程池的好处 a) 降低资源的消耗.使用线程池不用频繁的创建线程和销毁线程 b) 提高响应速度,任 ...
- Java 使用new Thread和线程池的区别
本文转至:https://www.cnblogs.com/cnmenglang/p/6273761.html , 孟凡柱的专栏 的博客,在此谢谢博主! 1.new Thread的弊端执行一个异步任务你 ...
- Java多线程并发04——合理使用线程池
在此之前,我们已经了解了关于线程的基本知识,今天将为各位带来,线程池这一技术.关注我的公众号「Java面典」了解更多 Java 相关知识点. 为什么使用线程池?线程池做的工作主要是控制运行的线程的数量 ...
- java多线程总结五:线程池的原理及实现
1.线程池简介: 多线程技术主要解决处理器单元内多个线程执行的问题,它可以显著减少处理器单元的闲置时间,增加处理器单元的吞吐能力. 假设一个服务器完成一项任务所需时间为:T1 创 ...
- Java 1.ExecutorService四种线程池的例子与说明
1.new Thread的弊端 执行一个异步任务你还只是如下new Thread吗? new Thread(new Runnable() { @Override public void run() { ...
- (Java多线程系列九)线程池
线程池 1.什么是线程池 线程池是指在初始化一个多线程应用程序过程中创建一个线程集合,然后在需要执行新的任务时重用这些线程而不是新建一个线程.线程池中线程的数量通常取决于可用内存数量和应用程序的需求. ...
- Java第二十七天,线程池
1.什么情况下需要线程池? 频絮创建线程就会大大降低系统的效率,那么有没有一种办法使得线程可以复用,就是执行完一个任务,并不被销毁,而是可以继续执行其他的任务?在java中可以通过线程池来达到这样的效 ...
- Java 四种内置线程池
引言 我们之前使用线程的时候都是使用 new Thread 来进行线程的创建,但是这样会有一些问题 每次 new Thread 新建对象性能差 线程缺乏统一管理,可能无限制新建线程,相互之间竞争,及可 ...
- Java 多线程(五)—— 线程池基础 之 FutureTask源码解析
FutureTask是一个支持取消行为的异步任务执行器.该类实现了Future接口的方法. 如: 取消任务执行 查询任务是否执行完成 获取任务执行结果(”get“任务必须得执行完成才能获取结果,否则会 ...
随机推荐
- Istio如何使用相同的端口访问网格外服务
1.1.背景 写这篇文章的目的是为了说明以下问题:如何使用TCP协议相同的端口访问网格外多个服务? 这是最近直播的时候有一个同学提出的,当时我没有完全明白,“访问多集群” 的意思.后来仔细思考了一下, ...
- SQL邮件服务(解决各种疑难杂症)+案例 + 使用SQLserver 邮件系统发送SQL代理作业执行警告
首先你需要知道你要做的几部: 1 每个数据库都有自己的 SERVICE BROKER 很多SQL SERVER内部服务依赖它 2 启动 SERVICE BROKER 需要 1 STOP 你的 SQL ...
- 修改servlet的模板代码
实际开发中,这些生成的代码和注释一般我们都用不到的,每次都要手工删除这些注释和代码,很麻烦.下面以MyEclipse 2014(其实版本通用的,都可以修改)为例进行说明如何修改Servlet的模板代码 ...
- final评论1
1-约跑APP 小组准备的非常的充分,还带了摄像头,发布过程清晰.团队的约跑项目界面相较于Beta版本进行了美化,增加了背景图片,使项目看起来更美观.同时项目支持聊天信息的接收和发送,个人觉得他们组的 ...
- HDU 2020 绝对值排序
http://acm.hdu.edu.cn/showproblem.php?pid=2020 Problem Description 输入n(n<=100)个整数,按照绝对值从大到小排序后输出. ...
- Windows 2012r2 以及以上版本远程提示错误的解决方法
部分机器远程时会提示如图: 其实解决问题非常简单 .... 为了防止不会操作 完整的截图展示. 服务器下面进行处理 打开我的电脑 属性 打开远程设置 将框中的选项取消掉 然后就可以了.
- 从苦逼到牛逼,详解Linux运维工程师的打怪升级之路
做运维也快四年多了,就像游戏打怪升级,升级后知识体系和运维体系也相对变化挺大,学习了很多新的知识点. 运维工程师是从一个呆逼进化为苦逼再成长为牛逼的过程,前提在于你要能忍能干能拼,还要具有敏锐的嗅觉感 ...
- linux 开机直接进入命令行
一.图形界面和命令行切换 linux系统在启动图形化界面后,可以在图形界面和命令行之间来回切换,linux提供了6个命令行终端(terminal或Console),分别为tty1——tty6,使用Ct ...
- letsencrypt续期 最简单的续期方法更新证书
Let's Encrypt申请的证书会有三个月的有效期,如何更方便的续期呢? 关于证书续期: 所谓letsencrypt续期,续期相当于重新申请一次证书,然后在服务器端将过期的证书替换掉即可.由于这个 ...
- Java学习之StringBuffer
1.类介绍 ①线程安全的可变字符串序列,一个类似于String的字符串缓冲区,但是不能修改(就是不能通过加号+连接,String就可以) ②StringBuffer和String类 ...