Java FutureTask

//FutureTask可用于异步获取执行结果或取消执行任务的场景
public class FutureTask implements RunnableFuture
public interface RunnableFuture extends Runnable, Future

1、代码示例

public class MainTest {

    public static void main(String[] args) throws Exception {
        FutureTask integerFutureTask = new FutureTask(new Callable() {
            @Override
            public Integer call() throws Exception {
                Random random = new Random();
                return random.nextInt(10);
            }
        });
        //直接调用其run方法或者放入线程池执行

        //执行方式1:
        integerFutureTask.run();

        //执行方式2:
        ExecutorService exec = Executors.newFixedThreadPool(5);
        //exec.submit(integerFutureTask);

        //执行方式3:
        /**
        List> list = new ArrayList<>();
        list.add(new Callable() {
            @Override
            public Integer call() throws Exception {
                Random random = new Random();
                return random.nextInt(10);
            }
        });
        List> futures = exec.invokeAll(list);
        int tempCount = futures.get(0).get();
        System.out.println("执行结果:" + tempCount);
        */
        int count = integerFutureTask.get();
        System.out.println("执行结果:" + count);

        FutureTask task = new FutureTask(new Callable() {
            @Override
            public Object call() throws Exception {
                for (int index = 1; index <= count; index++) {
                    System.out.println("休眠" + index + "秒");
                    Thread.sleep(1000);
                }
                return "执行完毕";
            }
        });
        task.run();
        System.out.println("执行结果:" + task.get());
    }

}

2、FutureTask在高并发环境下确保任务只执行一次

确保即使调用了多次run方法,它都只会执行一次Runnable或者Callable任务。
数据库的连接池、tair的连接池都是基于FutureTask来实现的,避免了加锁带来的性能问题。

连接池Demo

public class MainTest {

    private ConcurrentHashMap>
            connectionPool = new ConcurrentHashMap<>();

    public static void main(String[] args) throws Exception {
        MainTest mainTest = new MainTest();
        Connection connection = mainTest.getConnection("");
    }

    public Connection getConnection(String key) throws Exception {
        FutureTask connectionTask = connectionPool.get(key);
        if (connectionTask != null) {
            return connectionTask.get();
        } else {
            Callable callable = new Callable() {
                @Override
                public Connection call() throws Exception {
                    return createConnection();
                }
            };
            FutureTask newTask = new FutureTask<>(callable);
            connectionTask = connectionPool.putIfAbsent(key, newTask);
            if (connectionTask == null) {
                connectionTask = newTask;
                connectionTask.run();
            }
            return connectionTask.get();
        }
    }

    //创建Connection
    private Connection createConnection() {
        //todo
        return null;
    }

}

3、FutureTask 源码

FutureTask的get方法可以实现获取线程执行结果,或者设置超时时间获取线程执行结果 原理:

封装一个存放线程执行结果的变量A,使用AQS的独占API实现线程对变量A的独占访问。判断规则是,线程没有执行完毕:call()方法没有返回前,不能访问变量A;或者是超时时间没到前不能访问变量A。

FutureTask 深度解析

你可能感兴趣的:(Java FutureTask)