【问题标题】:Awaitility.await().atMost(...) causes program to exit if time out interval expires?如果超时间隔到期,Awaitility.await().atMost(...) 会导致程序退出?
【发布时间】:2013-10-28 04:48:14
【问题描述】:

这个问题是关于 com.jayway.awaitility.Awaitility。

我刚刚尝试了 Awaitility.await() ,它似乎有一些奇怪的行为。 在下面的测试方法中,如果我注释掉 testWithFuture() 并启用 testWithAwaitility(),我从来没有看到打印出消息“结束”。 我看到“开始”,然后程序就退出了,第二个 似乎永远无法到达 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
    }
 }

【问题讨论】:

    标签: java multithreading unit-testing concurrency


    【解决方案1】:

    根据documentation,如果达到超时且条件不成立,await() 将抛出TimeoutException,因此您的方法在此时结束,因为异常通过堆栈向上传播。这解释了这种行为。但是,您应该会看到堆栈跟踪。

    如果你想在之后继续执行代码,你似乎需要捕获这个异常。

    【讨论】:

    • 捕获异常有效。我使用您建议的更正编辑了原始帖子。谢谢。
    猜你喜欢
    • 2022-01-14
    • 1970-01-01
    • 1970-01-01
    • 2021-03-25
    • 1970-01-01
    • 2020-07-12
    • 1970-01-01
    • 1970-01-01
    • 2021-05-05
    相关资源
    最近更新 更多