最近项目用到一个功能需要实现多线程分发任务且需要任务的返回值,之前一直都是实现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. dataguard ORA-12514: TNS:listener does not currently know of service requested in connect descriptor

    错误的意思是listener 不知道连接解析器中的请求服务,这里要说静态监听和动态监听了动态注册是在instance启动的时候PMON进程根据init.ora中的instance_name,servi ...

  2. docker拉取慢(net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting head)

    systemctl restart docker在docker-hub拉取慢,因为服务器在外网 直接配置阿里云镜像就可以 首先: vim /etc/docker/daemon.json加入下面的那句 ...

  3. 基于XML的开发

    基于XML的开发 1.定义一个切面类 /** * Created by zejian on 2017/2/20.*/ public class MyAspectXML { public void be ...

  4. IT兄弟连 HTML5教程 使用盒子模型的浮动布局

    虽然使用绝对定位可以实现页面布局,但由于调整某个盒子模型时其他盒子模型的位置并不会跟着改变,所以并不是布局的首选方式.而使用浮动的盒子模型可以向左或向右移动,直到它的外边缘碰到包含它的盒子模型边框或另 ...

  5. Linux汇总

    Linux介绍以及VMware和Centos的安装 linux-VMtools安装 linux-创建/使用快照/克隆(类似windows中备份还原) linux目录结构 linux指令大全(归类整理) ...

  6. C lang:programe flow

    C language flow Xx_a Introduction C language flow,control program order. Xx_b Foundation satement:fo ...

  7. 知识图谱基础之RDF,RDFS与OWL 2

    https://zhuanlan.zhihu.com/p/32122644 看过之前两篇文章([1](为什么需要知识图谱?什么是知识图谱?——KG的前世今生), [2](语义网络,语义网,链接数据和知 ...

  8. 47-准备 Overlay 网络实验环境

    为支持容器跨主机通信,Docker 提供了 overlay driver,使用户可以创建基于 VxLAN 的 overlay 网络.VxLAN 可将二层数据封装到 UDP 进行传输,VxLAN 提供与 ...

  9. BZOJ2127/LG1646 happiness 新建点最小割

    问题描述 BZOJ2127 LG1646 题解 和文理分科差不多 收益最大 -> 损失最小 -> 最小割 分别新建点表示互相关系就行了 \(\mathrm{Code}\) #include ...

  10. python之字符串的拼接总结

    加号连接 1.通过+号连接起来 逗号连接 2.通过都好连接起来 但是,这里值得注意的是,只能用于print打印,赋值组操作会生成元组 直接连接 3.直接连接中间有无空格均可 %连接 在python2. ...