java高级---->Thread之FutureTask的使用
FutureTask类是Future 的一个实现,并实现了Runnable,所以可通过Excutor(线程池) 来执行,也可传递给Thread对象执行。今天我们通过实例来学习一下FutureTask的用法。
多线程中FutureTask的使用
一、FutureTask的简单使用
package com.huhx.chenhui.nio;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
public class CallableThreadTest implements Callable<Integer> {
public static void main(String[] args) {
CallableThreadTest threadTest = new CallableThreadTest();
FutureTask<Integer> future = new FutureTask<>(threadTest);
for (int i = 0; i < 10; i++) {
System.out.println(Thread.currentThread().getName() + " 的循环变更i的值" + i);
if (i == 2) {
new Thread(future, "有返回的线程").start();
}
}
try {
System.out.println("子线程的返回值:" + future.get());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
@Override
public Integer call() throws Exception {
int i = 0;
for (; i < 10; i++) {
System.out.println(Thread.currentThread().getName() + "" + i);
}
return i;
}
}
运行结果如下:
main 的循环变更i的值0
main 的循环变更i的值1
main 的循环变更i的值2
main 的循环变更i的值3
main 的循环变更i的值4
main 的循环变更i的值5
main 的循环变更i的值6
main 的循环变更i的值7
main 的循环变更i的值8
main 的循环变更i的值9
有返回的线程0
有返回的线程1
有返回的线程2
有返回的线程3
有返回的线程4
有返回的线程5
有返回的线程6
有返回的线程7
有返回的线程8
有返回的线程9
子线程的返回值:10
二、 FutureTask的get方法的超时测试
package com.linux.huhx.thread;
import java.util.concurrent.*;
public class FutureTest {
public static void main(String[] args) throws TimeoutException {
FutureTask<String> future = new FutureTask<String>(new Task());
new Thread(future).start();
try {
System.out.println(future.get(4L, TimeUnit.SECONDS));
System.out.println("main thread");
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
static class Task implements Callable<String> {
@Override
public String call() throws Exception {
System.out.println("begin: " + Thread.currentThread().getName() + ", " + System.currentTimeMillis());
TimeUnit.SECONDS.sleep(5);
return "hello";
}
}
}
运行的效果如下:
官方文档对于这个方法的说明如下:
Waits if necessary for at most the given time for the computation to complete, and then retrieves its result, if available.
FutureTask的原理分析
FutureTask类的继承结构如下:
public class FutureTask<V> implements RunnableFuture<V>
public interface RunnableFuture<V> extends Runnable, Future<V>
FutureTask重写了run()方法,代码如下:
public void run() {
if (state != NEW ||
!UNSAFE.compareAndSwapObject(this, runnerOffset, null, Thread.currentThread()))
return;
try {
Callable<V> c = callable;
if (c != null && state == NEW) {
V result;
boolean ran;
try {
result = c.call(); // 调用Callable类中的call方法
ran = true;
} catch (Throwable ex) {
result = null;
ran = false;
setException(ex);
}
if (ran)
set(result);
}
} finally {
// runner must be non-null until state is settled to prevent concurrent calls to run()
runner = null;
// state must be re-read after nulling runner to prevent leaked interrupts
int s = state;
if (s >= INTERRUPTING)
handlePossibleCancellationInterrupt(s);
}
}
FutureTask的get方法,得到线程执行返回的结果。
Object x = outcome;
if (s == NORMAL)
return (V)x;
作者:
huhx
出处: www.cnblogs.com/huhx
格言:你尽力了,才有资格说自己的运气不好。
版权:本文版权归作者huhx和博客园共有,欢迎转载。未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接,否则保留追究法律责任的权利。
出处: www.cnblogs.com/huhx
格言:你尽力了,才有资格说自己的运气不好。
版权:本文版权归作者huhx和博客园共有,欢迎转载。未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接,否则保留追究法律责任的权利。