【问题标题】:Finagle Future objects, are they reusable?Finagle 未来的对象,它们是可重用的吗?
【发布时间】:2012-10-16 20:19:17
【问题描述】:

我是 Finagle 的新手。我现在正在阅读某人的代码,发现 Future 对象在不同的​​连接操作中被重用。我的问题是这会导致 Future 对象被执行多次(在每个连接中),还是只会执行一次并存储结果以供以后连接?

例子:

Future<A> a= b
            .join(c)
            .flatMap(new SomeFunctionReturningA());

Future<Tuple2<A, B>> future1 = a.join(b);
Future<D> future2 = future1.flatMap(new SomeFunctionReturningD()); 
future2.get();

那么 b 会被执行两次,还是只执行一次?

【问题讨论】:

    标签: java twitter future finagle


    【解决方案1】:

    我自己写了一个快速测试:

    import com.twitter.util.Function;
    import com.twitter.util.Future;
    import java.util.Random;
    import org.junit.Test;
    import scala.Tuple2;
    
    public class FinagleFutureTest {
        int counter = 0;
    
        @Test
        public void test(){
            Counter counter = new Counter();
            Future<Counter> one = Future.value(counter).flatMap(new IncrementFunction());
            Future<Counter> two = one.flatMap(new IncrementFunction());
            Future<Tuple2<Counter, Counter>> three = two.join(one);
            Tuple2<Counter, Counter> tuple = three.flatMap(new TupleFunction()).get();
            System.out.println("one: "+ tuple._2().count+", "+tuple._2().randomInt);
            System.out.println("two: "+ tuple._1().count+", "+tuple._1().randomInt);
        }
    
        static class TupleFunction extends Function<Tuple2<Counter, Counter>, Future<Tuple2<Counter, Counter>>>{
    
            @Override
            public Future<Tuple2<Counter, Counter>> apply(Tuple2<Counter, Counter> t1) {
                return Future.value(t1);
            }
    
        }
    
        static class IncrementFunction extends Function<Counter, Future<Counter>>{
            @Override
            public Future<Counter> apply(Counter counter) {
                counter.add();
                return Future.value(counter);
            }
        }
    
        static class Counter{
            public int count = 0;
            public int randomInt;
            Counter(){
                Random random = new Random();
                randomInt = random.nextInt();
            }
            public void add(){
                count++;
            }
        }
    }
    

    结果如下:

    one: 2, 2009034289
    two: 2, 2009034289
    

    所以结论是Future对象不管参与多少join操作都只会执行一次。

    【讨论】:

      【解决方案2】:

      Future 只是一个值的容器,并且该值只会被设置一次! Future[T] 有不同的状态:

      • 设置为 T 类型的值
      • 设置异常

      当您在 Future A 上使用 map/flatMap 和函数 f 时,您只需创建一个新的 Future B,它将是前一个由函数 f 转换的结果。

      注意:

      • 如果未来A 尚未“填充”,您将有一个尚未填充的B
      • A 中设置值a 的线程也将执行f(a) 并在B 中设置值
      • 如果A 已经“填充”,那么map/flatMap 的调用者也将执行f(a),但它不会重新计算A 的值。
      • 您也可以使用onSuccess/onFailure,它只会注册一些代码,以便在未来获得其值时执行。

      【讨论】:

        【解决方案3】:

        Future 对象只执行一次。

        Finagle 使用 com.twitter.util.A Future 是一个尚不可用的值的句柄。

        使用 Future 的两种最基本的方法是: 阻塞并等待计算返回 注册一个回调,当计算最终成功或失败时调用 FuturePool 对象使您能够在其自己的线程上放置阻塞操作。

        您可以通过twitter blogfingale github对Finagle Future(Future Pool)有更多的了解

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2018-05-26
          • 2016-04-29
          • 1970-01-01
          • 2023-01-19
          • 2011-08-17
          • 2022-06-16
          • 2022-11-22
          • 2015-12-24
          相关资源
          最近更新 更多