一: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 和线程池的更多相关文章

  1. java多线程系列六、线程池

    一. 线程池简介 1. 线程池的概念: 线程池就是首先创建一些线程,它们的集合称为线程池. 2. 使用线程池的好处 a) 降低资源的消耗.使用线程池不用频繁的创建线程和销毁线程 b) 提高响应速度,任 ...

  2. Java 使用new Thread和线程池的区别

    本文转至:https://www.cnblogs.com/cnmenglang/p/6273761.html , 孟凡柱的专栏 的博客,在此谢谢博主! 1.new Thread的弊端执行一个异步任务你 ...

  3. Java多线程并发04——合理使用线程池

    在此之前,我们已经了解了关于线程的基本知识,今天将为各位带来,线程池这一技术.关注我的公众号「Java面典」了解更多 Java 相关知识点. 为什么使用线程池?线程池做的工作主要是控制运行的线程的数量 ...

  4. java多线程总结五:线程池的原理及实现

    1.线程池简介:     多线程技术主要解决处理器单元内多个线程执行的问题,它可以显著减少处理器单元的闲置时间,增加处理器单元的吞吐能力.        假设一个服务器完成一项任务所需时间为:T1 创 ...

  5. Java 1.ExecutorService四种线程池的例子与说明

    1.new Thread的弊端 执行一个异步任务你还只是如下new Thread吗? new Thread(new Runnable() { @Override public void run() { ...

  6. (Java多线程系列九)线程池

    线程池 1.什么是线程池 线程池是指在初始化一个多线程应用程序过程中创建一个线程集合,然后在需要执行新的任务时重用这些线程而不是新建一个线程.线程池中线程的数量通常取决于可用内存数量和应用程序的需求. ...

  7. Java第二十七天,线程池

    1.什么情况下需要线程池? 频絮创建线程就会大大降低系统的效率,那么有没有一种办法使得线程可以复用,就是执行完一个任务,并不被销毁,而是可以继续执行其他的任务?在java中可以通过线程池来达到这样的效 ...

  8. Java 四种内置线程池

    引言 我们之前使用线程的时候都是使用 new Thread 来进行线程的创建,但是这样会有一些问题 每次 new Thread 新建对象性能差 线程缺乏统一管理,可能无限制新建线程,相互之间竞争,及可 ...

  9. Java 多线程(五)—— 线程池基础 之 FutureTask源码解析

    FutureTask是一个支持取消行为的异步任务执行器.该类实现了Future接口的方法. 如: 取消任务执行 查询任务是否执行完成 获取任务执行结果(”get“任务必须得执行完成才能获取结果,否则会 ...

随机推荐

  1. spring boot 2.0 源码分析(五)

    在上一篇文章中我们详细分析了spring boot是如何准备上下文环境的,今天我们来看一下run函数剩余的内容.还是先把run函数贴出来: /** * Run the Spring applicati ...

  2. unity上传app store遇到的一些问题

    记录ios发布时遇到的一些问题 注:如果你是用mac开发,那就在Unity里直接BuildAndRun就直接可以导到XCode里,如果是win,那就先打包成ios包,在传导Xcode里打开,不过可能会 ...

  3. PAT甲题题解-1068. Find More Coins (30)-dp,01背包

    一开始没多想,虽然注意到数据N<=10^4的范围,想PAT的应该不会超时吧,就理所当然地用dfs做了,结果最后一组真的超时了.剪枝啥的还是过不了,就意识到肯定不是用dfs做了.直到看到别人说用0 ...

  4. Linux内核分析——第三周学习笔记20135308

    第三周 构造一个简单的Linux系统MenuOS 计算机三个法宝: 1.存储程序计算机 2.函数调用堆栈 3.中断 操作系统两把宝剑: 1.中断上下文的切换:保存现场和恢复现场 2.进程上下文的切换 ...

  5. 第二个spring冲刺第5天

    针对与昨天的讨论内容,今天进行了开会研讨给意见. 在今天中有了点进展,各方面都有改善,离程序的完成度又前进了一大步.

  6. 从编译DotNetOpenAuth中学到的程序集强签名知识

    1. 背景 最近在研究DotNetOpenAuth——OAuth的一个.NET开源实现,官方网站:http://dotnetopenauth.net/ . 从GitHub签出DotNetOpenAut ...

  7. Linux搭建好apache后,只有本地能访问,局域或外网不能访问

    由于防火墙的访问控制导致本地端口不能被访问. 解决方法: 1,直接关闭防火墙  systemctl stop firewalld.service #停止防火墙服务 systemctl disable ...

  8. Jmeter put 方法总结

    1.百度到很多关于jmeter put 方法的使用 ,但觉得都完全 下面我大致总结下 : >1.放入 url 中 如:www.*****.com?a=1&b=2 ; >2.放入到p ...

  9. ThreadLocal 与 Synchronized区别

    相同:ThreadLocal和线程同步机制都是为了解决多线程中相同变量的访问冲突问题.不同:Synchronized同步机制采用了“以时间换空间”的方式,仅提供一份变量,让不同的线程排队访问:而Thr ...

  10. developer roadmap

    developer roadmap https://balsamiq.com/ https://balsamiq.com/givingback/free/ https://balsamiq.cloud ...