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;

 

友情链接

 

转载于:https://www.cnblogs.com/huhx/p/baseusejavaFutureTask.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值