最近项目用到一个功能需要实现多线程分发任务且需要任务的返回值,之前一直都是实现Runnable接口,但里面的run方法是返回void的。后来在网上查了下JAVA1.5开始就有了Callable。

下面来看看如何倒腾下这个东西。

import java.util.concurrent.Callable;

/**
* @类说明 线程业务处理
* @author DavenTsang
* @date 2016-11-16
*
*/
public class PoolTask implements Callable<String> { private String id; @Override
public String call() throws Exception {
return "当前线程名:" + Thread.currentThread().getName() + ":" + id;
} public String getId() {
return id;
} public void setId(String id) {
this.id = id;
} }

先建立一个类实现Callable接口。一下是JDK的API对Callable接口的描述:

public interface Callable<V>

返回结果并且可能抛出异常的任务。实现者定义了一个不带任何参数的叫做 call 的方法。

Callable 接口类似于 Runnable,两者都是为那些其实例可能被另一个线程执行的类设计的。但是 Runnable 不会返回结果,并且无法抛出经过检查的异常。

Executors 类包含一些从其他普通形式转换成 Callable 类的实用方法。

V是需要返回的对象。

需要执行这个实现类,我们需要创建一个线程池

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletionService;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorCompletionService;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future; public class PoolUtils { //可伸缩线程池
private static ExecutorService cachedPool = Executors.newCachedThreadPool();
public static CompletionService<String> completionService = new ExecutorCompletionService<String>(cachedPool);
private PoolTask task;
public String addTask() throws InterruptedException, ExecutionException{
//添加任务
Future<String> future = completionService.submit(task);
//检查是否出现第二个线程进来
Thread.sleep(1000);
List<Future<String>> list = new ArrayList<Future<String>>();
System.out.println(completionService.take().get());
list.add(future);
return completionService.take().get();
} public PoolTask getTask() {
return task;
}
public void setTask(PoolTask task) {
this.task = task;
} }

Thread.sleep();调用这个方法是因为在前面添加任务是用一个线程数组调用,看下Executors.newCachedThreadPool();这个是否可以自己去根据需要创建线程。

我们再来看下submit()方法的源码,

public Future<V> submit(Callable<V> task) {
if (task == null) throw new NullPointerException();
RunnableFuture<V> f = newTaskFor(task);
executor.execute(new QueueingFuture(f));
return f;
}
  private class QueueingFuture extends FutureTask<Void> {
QueueingFuture(RunnableFuture<V> task) {
super(task, null);
this.task = task;
}
protected void done() { completionQueue.add(task); }
private final Future<V> task;
}

追一下源码会发现里面有个队列存在。submit添加一个任务就会放到队列里面。这样就不用我们显示的去创建一个队列。

调用类:

import java.util.concurrent.ExecutionException;

public class Test {

    public static void main(String[] args) throws InterruptedException, ExecutionException {
Thread[] thread = new Thread[10];
for(int i = 0;i<thread.length;i++){
thread[i] = new Thread(new A());
}
for(Thread th : thread){
th.start();
} }
} class A implements Runnable{
@Override
public void run() {
PoolTask task = new PoolTask();
task.setId("daven");
PoolUtils utils = new PoolUtils();
utils.setTask(task);
try {
String a = utils.addTask();
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
}

调用类用多个线程去调用是因为模拟项目的场景了。

以上是一些记录供自己回忆用。遇到问题先自己查找原因,再去网上找下然后再找API追源码。

Callable实现JAVA多线程的更多相关文章

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

    概要 本章介绍线程池中的Callable和Future.Callable 和 Future 简介示例和源码分析(基于JDK1.7.0_40) 转载请注明出处:http://www.cnblogs.co ...

  2. java:多线程基础之Runnable、Callable与Thread

    java.lang包下有二个非常有用的东西:Runnable接口与Thread类,Thread实现了Runnable接口(可以认为Thread是Runnable的子类),利用它们可以实现最基本的多线程 ...

  3. java多线程Future和Callable类的解释与使用

    一,描写叙述 ​在多线程下编程的时候.大家可能会遇到一种需求,就是我想在我开启的线程都结束时,同一时候获取每一个线程中返回的数据然后再做统一处理,在这种需求下,Future与Callable的组合就派 ...

  4. java多线程系列(七)---Callable、Future和FutureTask

    Callable.Future和FutureTask 前言:如有不正确的地方,还望指正. 目录 认识cpu.核心与线程 java多线程系列(一)之java多线程技能 java多线程系列(二)之对象变量 ...

  5. java多线程创建-Thread,Runnable,callable和threadpool

    java创建多线程的方式有许多种,这里简要做个梳理 1. 继承Thread类 继承java.lang.Thread类,创建本地多线程的类,重载run()方法,调用Thread的方法启动线程.示例代码如 ...

  6. java多线程(三)-Executors实现的几种线程池以及Callable

    从java5开始,类库中引入了很多新的管理调度线程的API,最常用的就是Executor(执行器)框架.Executor帮助程序员管理Thread对象,简化了并发编程,它其实就是在 提供了一个中间层, ...

  7. Java多线程编程:Callable、Future和FutureTask浅析(多线程编程之四)

    java多线程-概念&创建启动&中断&守护线程&优先级&线程状态(多线程编程之一)java多线程同步以及线程间通信详解&消费者生产者模式&死锁& ...

  8. java多线程开发,Executors、FutureTask、Callable

    java多线程如何应用呢,几乎学java的同学都知道Thread类和Runable接口.继承Thread类或者实现Runable接口,调用thread的start方法即可启动线程. 然后是线程池,就是 ...

  9. Java多线程 - Callable和Future

    已知的创建多线程的方法有继承Tread类和实现Runnable方法.此外Java还提供了Callable接口,Callable接口也提供了一个call()方法来做为线程执行体.但是call()方法与r ...

随机推荐

  1. How we implemented consistent hashing efficiently

    原文链接https://medium.com/ably-realtime/how-to-implement-consistent-hashing-efficiently-fe038d59fff2 我们 ...

  2. [洛谷P1967][题解]货车运输

    题目 这道题让我们求最小限重的最大值 显然可以先求出最大生成树,然后在树上进行操作 因为如果两点之间有多条路径的话一定会走最大的,而其他小的路径是不会被走的 然后考虑求最小权值 可以采用倍增求LCA, ...

  3. Spring Boot2解决idea console 控制台输出乱码

    Idea默认配置是采用GBK, 而项目工程文件采用的是UTF-8. 编码不一致,导致idea Console控制台输出乱码. 网上的解决方案,大都是直接修改Settings=>Editor=&g ...

  4. 精通awk系列(6):awk命令结构和awk语法结构

    回到: Linux系列文章 Shell系列文章 Awk系列文章 awk命令行结构和语法结构 awk命令行结构 awk [ -- ] program-text file ... (1) awk -f p ...

  5. mysql-5.7.27安装

    1,下载5.7.27安装包   百度网盘   (注:5.7.27要安装net faframework4.5.2) 2,创建my.ini及data文件 下载5.7.27后解压,在创建my.ini文件及d ...

  6. iOS开发WKWebView 返回H5上级页面

    #pragma mark ---- 点击事件 -(void)leftTapClick:(UITapGestureRecognizer *)sender{ //判断是否能返回到H5上级页面 if (se ...

  7. Github访问速度很慢的原因,以及解决方法

    1,CDN,Content Distribute Network,可以直译成内容分发网络,CDN解决的是如何将数据快速可靠从源站传递到用户的问题.用户获取数据时,不需要直接从源站获取,通过CDN对于数 ...

  8. C#&.Net干货分享- 构造BaiduLanguageHelper对接百度的语言翻译

    全部是封装的API源码... namespace Frame.Api{    /// <summary>    /// 百度多语言支持器    /// </summary>   ...

  9. 连接查询 变量、if else、while

    连接查询 变量.if else.while   一.连接查询:通过连接运算符可以实现多个表查询. 连接是关系数据库模型的主要特点,也是它区别于其它类型数据库管理系统的一个标志. 常用的两个链接运算符: ...

  10. Vue项目中使用jquery插件

    1.引入jquery,并且在vue.config.js里配置 config.plugin('provide') .use(webpack.ProvidePlugin, [{ $: 'jquery', ...