java — 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();
            }
        }//需要获取资料的朋友请加Q君样:290194256*
        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();
        }//需要获取资料的朋友请加Q君样:290194256*
    }

    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);
            }//需要获取资料的朋友请加Q君样:290194256*
            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;
在这里插入图片描述
在这里插入图片描述

最新2020整理收集的一些高频面试题(都整理成文档),有很多干货,包含mysql,netty,spring,线程,spring cloud、jvm、yua码、算法等详细讲解,也有详细的学习规划图,源码、面试题整理等,需要获取这些内容的朋友请加Q君样:290194256*

猜你喜欢

转载自blog.csdn.net/weixin_53341657/article/details/112912481