美文网首页线程
Java FutureTask

Java FutureTask

作者: 韭菜待收割 | 来源:发表于2018-10-22 17:09 被阅读7次
    //FutureTask可用于异步获取执行结果或取消执行任务的场景
    public class FutureTask<V> implements RunnableFuture<V>
    public interface RunnableFuture<V> extends Runnable, Future<V>
    

    1、代码示例

    public class MainTest {
    
        public static void main(String[] args) throws Exception {
            FutureTask<Integer> integerFutureTask = new FutureTask<Integer>(new Callable<Integer>() {
                @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<Callable<Integer>> list = new ArrayList<>();
            list.add(new Callable<Integer>() {
                @Override
                public Integer call() throws Exception {
                    Random random = new Random();
                    return random.nextInt(10);
                }
            });
            List<Future<Integer>> 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来实现的,避免了加锁带来的性能问题。

    public class MainTest {
    
        private ConcurrentHashMap<String, FutureTask<Connection>>
                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<Connection> connectionTask = connectionPool.get(key);
            if (connectionTask != null) {
                return connectionTask.get();
            } else {
                Callable<Connection> callable = new Callable<Connection>() {
                    @Override
                    public Connection call() throws Exception {
                        return createConnection();
                    }
                };
                FutureTask<Connection> 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

        本文链接:https://www.haomeiwen.com/subject/zfwgzftx.html