全屏浏览
缩小浏览
回到页首

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";
        }
    }
}

运行的效果如下:

img

官方文档对于这个方法的说明如下:

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;

posted @ 2017-07-26 09:45  huhx  阅读(961)  评论(0编辑  收藏  举报