1

この質問は、com.jayway.awaitility.Awaitility に関するものです。

Awaitility.await() を試したところ、奇妙な動作をしているようです。以下のテスト メソッドで、testWithFuture() をコメント アウトして testWithAwaitility() を有効にすると、「 end 」というメッセージが出力されません。「start」と表示された後、プログラムが終了し、2 番目の print ステートメントに到達していないようです。

そのため、回避策として Settable{Future} を使用することにしました..他の誰かが同じ問題を抱えている場合は、私が提供する回避策が役立つかもしれません..良い答えを得ることがさらに良いでしょう; ^) ! 前もって感謝/クリス

コード:


import com.google.common.util.concurrent.SettableFuture;

import java.util.Date;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import static com.jayway.awaitility.Awaitility.await;
import static java.util.concurrent.TimeUnit.SECONDS;

public class AwaitTest {
    static volatile boolean done = false;

    public static void main(String[] args) throws InterruptedException, ExecutionException, TimeoutException {
        testWithFuture();
        //testWithAwaitility();
    }

    private static void testWithAwaitility() {
        System.out.println("start " + new Date());
        new Thread(new Runnable(){
            public void run(){
                try {
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                done = true;
            }

        }).start();


        await().atMost(2, SECONDS).until(new Callable() {
            @Override
            public Boolean call() throws Exception {
                return done;
            }
        });

        System.out.println("end " + new Date());   // NEVER Reached. i wonder why?

    }

    // This does what I want.
    //
    private static void testWithFuture() throws InterruptedException, ExecutionException, TimeoutException {
        System.out.println("start testWithFuture");

        final SettableFuture future = SettableFuture. create();
        new Thread(new Runnable(){

            public void run(){
                try {
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
                    e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
                }
                future.set("Hello");
            }

        }).start();

        String result = future.get(4, TimeUnit.SECONDS);

        if (! result.equals("Hello")) {
            throw new RuntimeException("not equal");
        } else {
            System.out.println("got Hello");

        }
    }
 }

正しいコード ->

import java.util.Date;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import static com.jayway.awaitility.Awaitility.await;
import static java.util.concurrent.TimeUnit.SECONDS;

public class Sample {
    static volatile boolean done = false;

    public static void main(String[] args) {
        testWithAwaitility();
    }

    private static void testWithAwaitility() {
        System.out.println("start " + new Date());
        new Thread(new Runnable(){
            public void run(){
                try {
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                done = true;
            }

        }).start();


        try {
            await().atMost(2, SECONDS).until(new Callable() {
                @Override
                public Boolean call() throws Exception {
                    return done;
                }
            });
        } catch (Exception e) {
            System.out.println("FAILED");
            e.printStackTrace();
        }


        System.out.println("end " + new Date());   // REACHED this statement after correction
    }
 }
4

1 に答える 1

5

ドキュメントによると、タイムアウトに達し、条件が真でない場合await()は a をスローしTimeoutExceptionます。そのため、例外がスタックを介して伝播されるため、メソッドはこの時点で終了します。これは動作を説明します。ただし、スタックトレースが表示されるはずです。

その後もコードを実行したい場合は、この例外をキャッチする必要があるようです。

于 2013-10-28T06:14:46.320 に答える