Coin163

首页 > Java多线程之 Callable、Future和FutureTask

Java多线程之 Callable、Future和FutureTask

相关标签: callable java future 多线程

2021腾讯云限时秒杀,爆款1核2G云服务器298元/3年!(领取2860元代金券),
地址https://cloud.tencent.com/act/cps/redirect?redirect=1062

2021阿里云最低价产品入口+领取代金券(老用户3折起),
入口地址https://www.aliyun.com/minisite/goods

相关推荐:Java中的Runnable、Callable、Future、FutureTask的区别与示例

(转载)http://blog.csdn.net/bboyfeiyu/article/details/24851847 Java中存在Runnable、Callable、Future、FutureTask这几个与线程相关的类或者接口,在Java中也是比较重要的几个概念,我们通过下面的简单示例来了解一下它们的作用于区别。 Runnable 其中Ru

最近在研究Android AsyncTask 源码的时候,发现用到了很多JAVA SE 多线程的知识,于是回过头来查阅JDK 文档复习了一下Java多线程的相关知识,做一个笔记方便以后查找。 JDK API 中关于Callable介绍 Callable 接口类似于 Runnable,两者都是为那些其实例可能被另一个线程执行的类设计的。但是Runnable 不会返回结果,并且无法抛出经过检查的异常。

我们可以通过 ExecutorService 的submit 方法来提交一个Runnable或者Callable任务,并且会返回一个Future对象。 Future 表示异步计算的结果,我们可以通过 Future 对象来获取计算的结果 或者是 取消正在进行的任务。 下面通过一个例子来比较Runnable和Callable的不同之处。 package com.example.test.callable;import java.util.concurrent.Callable;import java.util.concurrent.ExecutionException;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import java.util.concurrent.Future;public class CallableTest {

/**

* @param args

*/

public static void main(String[] args) {

// testRunnable();

testCallable();

}

private static void testCallable() {

ExecutorService pool = Executors.newFixedThreadPool(3);

CalculateCallable task1 = new CalculateCallable(0);

CalculateCallable task2 = new CalculateCallable(1);

CalculateCallable task3 = new CalculateCallable(3);

try {

// 提交并执行任务,任务启动时返回了一个 Future对象,

// 如果想得到任务执行的结果或者是异常可对这个Future对象进行操作

Future<Integer> future1 = pool.submit(task1);

// 获得第一个任务的结果,如果调用get方法,当前线程会等待任务执行完毕后才往下执行

System.out.println("task1 get: " + future1.get());

Future<Integer> future2 = pool.submit(task2);

// System.out.println("task2 get: " + future2.get(2000,

// TimeUnit.MILLISECONDS));

// 等待5秒后,再停止第二个任务,因为第二个任务进行的是无限循环

Thread.sleep(8000);

System.out.println("task2 cancel: " + future2.cancel(true));

Future<Integer> future3 = pool.submit(task3);

System.out.println("task3 get: " + future3.get());

} catch (InterruptedException e) {

e.printStackTrace();

} catch (ExecutionException e) {

e.printStackTrace();

}

// 停止任务执行服务

pool.shutdownNow();

}

private static void testRunnable() {

CalculateRunnable task1 = new CalculateRunnable(0);

CalculateRunnable task2 = new CalculateRunnable(1);

CalculateRunnable task3 = new CalculateRunnable(3);

ExecutorService pool = Executors.newFixedThreadPool(3);

try {

Future<?> future1 = pool.submit(task1);

System.out.println("task1 get: " + future1.get());

Future<?> future2 = pool.submit(task2);

// System.out.println("task2 get: " + future2.get());

// 等待5秒后,再停止第二个任务

Thread.sleep(8000);

System.out.println("task2 cancel: " + future2.cancel(true));

Future<?> future3 = pool.submit(task3);

System.out.println("task3 get: " + future3.get());

} catch (InterruptedException e) {

e.printStackTrace();

} catch (ExecutionException e) {

e.printStackTrace();

}

// 停止任务执行服务

相关推荐:Java并发编程实践:Callable异步回调Future、FutureTask用法

Callable接口类似于Runnable,从名字就可以看出来了,但是Runnable不会返回结果,并且无法抛出返回结果的异常,而Callable功能更强大一些,被线程执行后,可以返回值,这个返回值可以被Future拿到。FutureTask实现了两个接口,Runnable和Future,所以它既可以

pool.shutdownNow();

}

public static class CalculateCallable implements Callable<Integer> {

private int param = -1;

public CalculateCallable(int param) {

this.param = param;

}

@Override

public Integer call() throws Exception {

if (this.param == 0) {

System.out.println("no loop********" + param);

return 0;

} else if (this.param == 1) {

// 如果flag的值为1,做一个无限循环

try {

while (true) {

System.out.println("while looping********" + param);

Thread.sleep(2000);

}

} catch (InterruptedException e) {

System.out.println("Interrupted");

}

return 1;

} else {

throw new Exception("illegal argument!"+param);

}

}

}

public static class CalculateRunnable implements Runnable {

private int param = -1;

public CalculateRunnable(int param) {

this.param = param;

}

@Override

public void run() {

if (this.param == 0) {

System.out.println("param=" + param + "***over");

} else if (this.param == 1) {

// 如果flag的值为1,做一个无限循环

try {

while (true) {

System.out.println("looping********" + param);

Thread.sleep(2000);

}

} catch (InterruptedException e) {

System.out.println("Interrupted");

}

System.out.println("param=" + param + "***over");

} else {

System.out.println("illegal argument!"+param);

}

}

}} FutureTask,可取消的异步计算。仅在计算完成时才能获取结果;如果计算尚未完成,则阻塞 get 方法。 package com.example.test.callable;import java.util.concurrent.Callable;import java.util.concurrent.ExecutionException;import java.util.concurrent.FutureTask;public class FutureTaskTest {

/**

* @param args

*/

public static void main(String[] args) {

testFutureTask();

}

private static void testFutureTask() {

Worker worker = new Worker(); // 工作线程

FutureTask<Integer> ft = new FutureTask<Integer>(worker);

new Thread(ft).start();

while (!ft.isDone()) {

try {

System.out.println("monitor worker thread...");

Thread.sleep(500);

} catch (InterruptedException e) {

e.printStackTrace();

}

}

try {

int amount = ft.get();

//返回值

System.out.println("amount="+amount);

} catch (InterruptedException e) {

e.printStackTrace();

} catch (ExecutionException e) {

e.printStackTrace();

}

}

public static class Worker implements Callable<Integer> {

private int flag = 100;

private int retVal = 0;

@Override

public Integer call() throws Exception {

while (flag > 0) {

System.out.println("I'm working......"+flag);

flag--;

retVal++;

Thread.sleep(1000);

}

return retVal;

}

}}

原文

最近在研究Android AsyncTask 源码的时候,发现用到了很多JAVA SE 多线程的知识,于是回过头来查阅JDK 文档复习了一下Java多线程的相关知识,做一个笔记方便以后查找。 JDK API 中关于Callable

------分隔线----------------------------