Java中的Runable,Callable,Future,FutureTask,ExecutorService,Excetor,Excutors,ThreadPoolExcetor在这里对这些关键词,以及它们的用法做一个总结。

首先将它们分个类:

Runable,Callable

Future,FutureTask

ExecutorService,Executor,Excutors,ThreadPoolExcetor

  1. 关于Ranable和Callable

    --

    首先Java中创建线程的方法有三种:
  2. 继承Thread类,覆盖run方法
  3. 实现Runable接口,实现run方法
  4. 实现Callable接口,实现run方法

三种实现的优缺点:

  1. 继承Thread,单继承的缘故,不能再继承其他类,获取当前线程this
  2. 实现Runable接口,没有返回值,获取当前线程Thread.currentThread()
  3. 实现Callable接口,可通过Future.get()获取返回值,获取当前线程 Thread.currentThread()

继承Thread,两个步骤:

class DemoThread extends Thread {
@Override
public void run() {
super.run();
// Perform time-consuming operation...
}
}
DemoThread t = new DemoThread();
t.start();
  • 继承Thread类,覆盖run()方法。
  • 创建线程对象并用start()方法启动线程。

实现Runable,一般使用如下:

new Thread(new Runnable() {
@Override
public void run() {
// do something
}
}).start();

为了简单。

以上两种方式获取线程执行的结果相当麻烦,不能直接获取。JDK1.5增加了 Callable, Callable 的 call() 方法可以返回值和抛出异常。Callable 可以返回装载有计算结果的 Future 对象。

Callable的源码:

public interface Callable<V> {
V call() throws Exception;
}

Callable的基本使用方法:

FutureTask<Integer> futureTask = new FutureTask<Integer>(new Callable<Integer>() {
@Override
public Integer call() throws Exception {
// do something
return null;
}
});
Thread thread = new Thread(futureTask);
thread.start();
Integer result = futureTask.get();

运行 Callable 任务可以拿到一个 Future 对象,通过Future的get()方法拿到线程执行的返回值。那么...Future,FutureTask区别是什么,怎么使用?

->next()

  1. 关于Future和FutureTask

    --

    为了获取线程的执行结果,引入了Future的FutureTask,那么他们是什么关系,如何使用?

    Future类位于java.util.concurrent包下,它是一个接口:
public interface Future<V> {
boolean cancel(boolean mayInterruptIfRunning);
boolean isCancelled();
boolean isDone();
V get() throws InterruptedException, ExecutionException;
V get(long timeout, TimeUnit unit)
throws InterruptedException, ExecutionException, TimeoutException;
}

Future 定义了5个方法:

  1. boolean cancel(boolean mayInterruptIfRunning):试图取消对此任务的执行。如果任务已完成、或已取消,或者由于某些其他原因而无法取消,则此尝试将失败。当调用 cancel() 时,如果调用成功,而此任务尚未启动,则此任务将永不运行。如果任务已经启动,则 mayInterruptIfRunning 参数确定是否应该以试图停止任务的方式来中断执行此任务的线程。此方法返回后,对 isDone() 的后续调用将始终返回 true。如果此方法返回 true,则对 isCancelled() 的后续调用将始终返回 true。
  2. boolean isCancelled():如果在任务正常完成前将其取消,则返回 true。
  3. boolean isDone():如果任务已完成,则返回 true。 可能由于正常终止、异常或取消而完成,在所有这些情况中,此方法都将返回 true。
  4. V get()throws InterruptedException,ExecutionException:如有必要,等待计算完成,然后获取其结果。
  5. V get(long timeout,TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException: 如有必要,最多等待为使计算完成所给定的时间之后,获取其结果(如果结果可用)。

总的来说Future提供了三种功能:

  1. 判断任务是否完成;
  2. 能够中断任务;
  3. 能够获取任务执行结果。

重点

RunnableFuture继承了Runnable接口和Future接口,而FutureTask实现了RunnableFuture接口。

FutureTask的实现:

public class FutureTask<V> implements RunnableFuture<V>

RunnableFuture接口的实现:

public interface RunnableFuture<V> extends Runnable, Future<V> {
void run();
}

FutureTask是Future接口的一个唯一实现类。

除了可以用Thread包装FutureTask外,还有另一种使用方法:

ExecutorService executor = Executors.newCachedThreadPool();
FutureTask<Integer> futureTask = new FutureTask<Integer>(new Callable<Integer>() {
@Override
public Integer call() throws Exception {
// do something
return null;
}
});
executor.submit(futureTask);
Integer result = futureTask.get();

这里用到了Executor 框架。

->next();

  1. 关于ExecutorService,Executor,Excutors,ThreadPoolExcetor

    --

    Executor框架在Java 5中被引入,Executor 框架是一个根据一组执行策略调用、调度、执行和控制的异步任务的框架。

    在说Executor 框架之前我们需要引入一个新的概念——线程池(ThreadPoolExecutor):
public ThreadPoolExecutor(intcorePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler)

ThreadPoolExecutor是Executors类的底层实现。

在JDK帮助文档中,有如此一段话:

“强烈建议程序员使用较为方便的 Executors 工厂方法 Executors.newCachedThreadPool()(无界线程池,可以进行自动线程回收)、Executors.newFixedThreadPool(int)(固定大小线程池)和 Executors.newSingleThreadExecutor()(单个后台线程),它们均为大多数使用场景预定义了设置。”

那么ExecutorService,Excetor,Excutors都是什么?

Excetor是一个抽象层面的核心接口:

public interface Executor {
void execute(Runnable command);
}

ExecutorService 接口 对 Executor 接口进行了扩展,提供了返回 Future 对象,终止,关闭线程池等方法。

public interface ExecutorService extends Executor {
void shutdown();
<T> Future<T> submit(Callable<T> task);
<T> Future<T> submit(Runnable task, T result);
<T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks, long timeout, TimeUnit unit) throws InterruptedException;
}

Executors 是一个工具类,类似于 Collections。提供工厂方法来创建不同类型的线程池,比如 FixedThreadPool 或 CachedThreadPool。

public class Executors {
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS,new LinkedBlockingQueue<Runnable>());
} public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, new SynchronousQueue<Runnable>());
}
}

以上是对Java多线程关键词的整理,不至于一团乱麻。

Java中实现多线程关键词整理的更多相关文章

  1. Java中的多线程=你只要看这一篇就够了

    如果对什么是线程.什么是进程仍存有疑惑,请先Google之,因为这两个概念不在本文的范围之内. 用多线程只有一个目的,那就是更好的利用cpu的资源,因为所有的多线程代码都可以用单线程来实现.说这个话其 ...

  2. JAVA中去掉空格经典整理

    JAVA中去掉空格经典整理 JAVA中去掉空格          1. String.trim() --------------trim()是去掉首尾空格           2.str.replac ...

  3. Java 中传统多线程

    目录 Java 中传统多线程 线程初识 线程的概念 实现线程 线程的生命周期 常用API 线程同步 多线程共享数据的问题 线程同步及实现机制 线程间通讯 线程间通讯模型 线程中通讯的实现 @(目录) ...

  4. Java中使用多线程、curl及代理IP模拟post提交和get访问

    Java中使用多线程.curl及代理IP模拟post提交和get访问 菜鸟,多线程好玩就写着玩,大神可以路过指教,小弟在这受教,谢谢! 更多分享请关注微信公众号:lvxing1788 ~~~~~~ 分 ...

  5. 【转】Java中的多线程学习大总结

    多线程作为Java中很重要的一个知识点,在此还是有必要总结一下的. 一.线程的生命周期及五种基本状态 关于Java中线程的生命周期,首先看一下下面这张较为经典的图: 上图中基本上囊括了Java中多线程 ...

  6. Java中的 多线程编程

    Java 中的多线程编程 一.多线程的优缺点 多线程的优点: 1)资源利用率更好2)程序设计在某些情况下更简单3)程序响应更快 多线程的代价: 1)设计更复杂虽然有一些多线程应用程序比单线程的应用程序 ...

  7. java中的多线程 // 基础

    java 中的多线程 简介 进程 : 指正在运行的程序,并具有一定的独立能力,即 当硬盘中的程序进入到内存中运行时,就变成了一个进程 线程 : 是进程中的一个执行单元,负责当前程序的执行.线程就是CP ...

  8. Android学习记录(5)—在java中学习多线程下载之断点续传②

    在上一节中我们学习了在java中学习多线程下载的基本原理和基本用法,我们并没有讲多线程的断点续传,那么这一节我们就接着上一节来讲断点续传,断点续传的重要性不言而喻,可以不用重复下载,也可以节省时间,实 ...

  9. Java中使用多线程、curl及代理IP模拟post提交和get訪问

    Java中使用多线程.curl及代理IP模拟post提交和get訪问 菜鸟,多线程好玩就写着玩.大神能够路过不吝赐教.小弟在这受教.谢谢! 很多其它分享请关注微信公众号:lvxing1788 ~~~~ ...

随机推荐

  1. 任务调度之持久化(基于Quartz.net)

    上一篇我们了解了任务调度及他的远端管理方式,传送门:任务调度及远端管理(基于Quartz.net) 这篇我们要完成任务调度的持久化功能,即新增修改删除之类的功能,这必须得要有的,不然都不知道后台都有什 ...

  2. 持续集成:TestNG组织如何测试用例 1

    持续集成:TestNG组织如何测试用例   poptest是国内唯一一家培养测试开发工程师的培训机构,以学员能胜任自动化测试,性能测试,测试工具开发等工作为目标.如果对课程感兴趣,请大家咨询qq:90 ...

  3. 聊天界面使用IQKeyboardManager导航栏及整个页面上移的解决方法

    问题: 使用第三方库IQKeyboardManager时会使整个页面上移,导航栏页偏移出了显示范围.在聊天界面就会使得上面的消息看不到. 解决方法: 首先说明:在聊天界面使用IQKeyboardMan ...

  4. 伸展树(Splay树)的简要操作

    伸展树(splay树),是二叉排序树的一种.[两个月之前写过,今天突然想写个博客...] 伸展树和一般的二叉排序树不同的是,在每次执行完插入.查询.删除等操作后,都会自动平衡这棵树.(说是自动,也就是 ...

  5. elasticsearch5.3安装插件head

    1.下载并配置nodejscd /usr/local/src/wget https://nodejs.org/dist/v6.9.5/node-v6.9.5-linux-x64.tar.xz & ...

  6. Node.js基本开发流程

    创建一个hello world: 1.打开一个文本编辑器,在其中输入console.log("hello world"),并保存为hello.js; 注意:输入中文如果编码不是ut ...

  7. 【Scala】Scala之Traits

    一.前言 前面学习了Scala中包和导入的相关知识点,接着学习Traits(特质) 二.Traits Scala的特质与Java的接口基本相同,当遇到可以使用Java接口的情形,就可以考虑使用特质,S ...

  8. jquery-ul-li实现分页功能 转载仅供交流

    js文件代码: (function($){ $.fn.Pages = function(options){ var opts = $.extend({},$.fn.Pages.defaults, op ...

  9. 【shell编程基础0】bash shell编程的基本配置

    前面一篇“shell编程之变量篇”主要讲述下shell编程的变量的基本知识:设置变量的方式,自定义变量和环境变量的差别,变量的替换.删除.测试等. 这一篇主要是讲述在bash shell下的一些基本配 ...

  10. GitHub上最受欢迎的iOS开源项目TOP20

    AFNetworking 在众多iOS开源项目中,AFNetworking可以称得上是最受开发者欢迎的库项目.AFNetworking是一个轻量级的iOS.Mac OS X网络通信类库,现在是GitH ...