【问题标题】:Wait for a flag等一个flag
【发布时间】:2015-03-19 17:18:27
【问题描述】:

我必须测试 Flash Player 是否正确地通过网络发送请求。为此,我使用 BrowserMob 代理来捕获流量。 我的问题是我必须等待播放的视频结束才能测试最终请求。所以作为临时解决方案,在我的测试中,我放了一个 Thread.sleep(videoDuration)。但 IMO 并不是很好,总体而言,持续时间可能会改变。 BrowserMob 允许在请求上添加拦截器。所以我想到了通知和等待功能。

这是我的第一次尝试:

protected static boolean percent100Done;

protected static final Object percent100lock = new Object();

@BeforeClass
public static void addInterceptor() {
    ProxyServer server = Server.init();
    server.addRequestInterceptor((BrowserMobHttpRequest request, Har har) -> {
        String percent = request.getProxyRequest().getParameter("percent");
        if("100".equals(percent)) {
            percent100Done = true;
            synchronized (percent100lock) {
                percent100lock.notify();
            }
        }
    });
}

@Test
public void testFinalRequest() throws InterruptedException {
    driver.get(myurl);
    synchronized (percent100lock) {
        while (!percent100Done) {
            percent100lock.wait();
        }
    }
    //test continue
}

我测试了这段代码,它可以工作。但它似乎有点脏,尤其是新的 Object 行。如果我必须为 25%、50% 和 75% 添加通知会怎样?我将需要 3 个其他布尔值并锁定?

【问题讨论】:

    标签: java multithreading wait notify


    【解决方案1】:

    为什么不存储百分比并有一个通用的“进度”事件,比如how XMLHTTPRequest works

    protected static int percent;
    protected static final Object progressLock = new Object();
    
    @BeforeClass
    public static void addInterceptor() {
        ProxyServer server = Server.init();
        server.addRequestInterceptor((BrowserMobHttpRequest request, Har har) -> {
            synchronized(progressLock) {
                percent = Integer.parseInt(request.getProxyRequest().getParameter("percent"));
                progressLock.notify();
            }
        });
    }
    
    @Test
    public void testFinalRequest() throws InterruptedException {
        driver.get(myurl);
        synchronized (progressLock) {
            int lastPercent = -1;
            while (percent != 100) {
                if (lastPercent < 50 && percent >= 50) {
                    System.out.println("50%");
                }
                lastPercent = percent;
                progressLock.wait();
            }
        }
        //test continue
    }
    

    就怪异而言,我认为您的解决方案很好。看起来很奇怪,但是每个Object 都有一个锁,所以你不妨使用它。如果你需要做一些更复杂的事情,你可能想看看Lock 和它的子类。例如,ReadWriteLock,多个读者可以同时持有锁,但只有一个写者可以。不过,看起来您并没有多个阅读器(而且我不认为锁定会对这个程序的性能产生太大影响)。

    【讨论】:

    • 感谢您的提示。使用 percent 变量而不是 100percent 变量非常聪明。关于锁定和条件,如果我理解正确的话,对您来说,仅仅出于性能原因使用它们没有意义吗?如果我们只讨论可读性,Lock 和 Condition 有帮助吗?
    • @tetienne synchronized 可能更容易阅读,因为它是 Java 自动处理的块。对于Lock 对象,您需要try / finally 才能在InterruptedException(或RuntimeExceptions)的情况下正确解锁它。对于性能,最好对其进行基准测试,但我怀疑在这种情况下性能是否重要。
    猜你喜欢
    • 2014-04-03
    • 1970-01-01
    • 1970-01-01
    • 2013-11-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多