12

他のスレッドで完了する2つのListenableFutureがあります。それぞれの未来は異なるタイプであり、両方が完成したときに両方の結果を使用したいと思います。

Guavaを使用してこれを処理するエレガントな方法はありますか?

4

5 に答える 5

4
Runnable listener = new Runnable() {
    private boolean jobDone = false;

    @Override
    public synchronized void run() {
        if (jobDone || !(future1.isDone() && future2.isDone())) {
            return;
        }
        jobDone = true;
        // TODO do your job
    }
};
future1.addListener(listener);
future2.addListener(listener);

それほどエレガントではありませんが、仕事をする必要があります。

または、よりエレガントですが、キャストが必要になります。

ListenableFuture<List<Object>> composedFuture = 
    Futures.allAsList(future1, future2);
于 2012-12-07T13:07:35.470 に答える
1

Guava v20.0以降、次を使用できます:

ListenableFuture<CombinedResult> resultFuture =
   Futures.whenAllSucceed(future1, future2)
       .call(callableThatCombinesAndReturnsCombinedResult, executor);

ここでJavaドキュメントの例を見てください

于 2018-11-20T10:12:24.750 に答える
0

以下は、2 つのリッスン可能な Future の追加を実行する簡単な例です。

//Asynchronous call to get first value
final ListenableFuture<Integer> futureValue1 = ...;

//Take the result of futureValue1 and transform it into a function to get the second value
final AsyncFunction<Integer, Integer> getSecondValueAndSumFunction = new AsyncFunction<Integer, Integer>() {
    @Override
    public ListenableFuture<Integer> apply(final Integer value1) {

        //Asynchronous call to get second value
        final ListenableFuture<Integer> futureValue2 = ...;


        //Return the sum of the values
        final Function<Integer, Integer> addValuesFuture = new Function<Integer, Integer>() {
            @Override
            public Integer apply(Integer value2) {

                Integer sum = value1 + value2;
                return sum;
            }               
        };              

        //Transform the second value so its value can be added to the first
        final ListenableFuture<Integer> sumFuture = Futures.transform(futureValue2, addValuesFuture);   

        return sumFuture;
    }
};

final ListenableFuture<Integer> valueOnePlusValueTwo = Futures.transform(futureValue1, getSecondValueAndSumFunction);   
于 2016-02-23T20:31:35.780 に答える
0

型の安全性が必要な場合はEventBus、姉妹の Guavacom.google.common.eventbusパッケージを使用して、2 つの異なる独立したタスクの結果を組み合わせることができます。

例として、あなたの 1 人がFutures戻っIntegerてきて、もう1 人がDouble.

まず、EventBus でイベント シンクとして登録するアキュムレータ (別名buildercollectorなど) クラスを作成します。Integerご覧のとおり、これは実際にはDoubleイベントを処理する POJO です。

class Accumulator
{
    Integer intResult;
    Double  doubleResult;

    @Subscribe // This annotation makes it an event handler
    public void setIntResult ( final Integer val )
    {
        intResult = val;
    }

    @Subscribe
    public void setDoubleResult ( final Double val )
    {
        doubleResult = val;
    }
}

これは、2 つの先物を取り、それらをアキュムレータに結合するメソッドの実装です。

final ListenableFuture< Integer > future1 = ...;
final ListenableFuture< Double > future2 = ...;

final ImmutableList< ListenableFuture< ? extends Object> > futures =
    ImmutableList.< ListenableFuture<? extends Object> >of( future1, future2 );

final ListenableFuture< Accumulator > resultFuture =
    Futures.transform(
        // If you don't care about failures, use allAsList
        Futures.successfulAsList( futures ),
        new Function< List<Object>, Accumulator > ( )
        {
            @Override
            public Accumulator apply ( final List< Object > input )
            {
                final Accumulator accumulator = new Accumulator( );

                final EventBus eventBus = new EventBus( );
                eventBus.register( accumulator );

                for ( final Object cur: input )
                {
                    // Failed results will be set to null
                    if ( cur != null )
                    {
                        eventBus.post( cur );
                    }
                }

                return accumulator;
            }
        }
    );

final Accumulator accumulator = resultFuture.get( );
于 2013-03-22T16:31:02.867 に答える