gpt4 book ai didi

java - 在 Java 中测试简单的信号量使用

转载 作者:塔克拉玛干 更新时间:2023-11-02 20:06:08 28 4
gpt4 key购买 nike

我有管理多个线程可能使用的信息的字段。访问这些字段至关重要,因此我实例化了一个信号量:

Semaphore semaphore = new Semaphore(1);

每个方法都尝试获取信号量,如果没有信号量则基本上锁定:

public void method()
{
semaphore.acquire();
doStruff();
cleanUp()
}

//Other methods using the same basic layout as the method above.

public void cleanUp()
{
//watch for state consistency and do some clean up
semaphore.release();
}

如果知道以下内容,我将如何着手测试上述内容:

  • 我不想使用定时测试,使用 Thread.sleep(x),因为该方法存在固有问题,例如依赖时钟和对该方法缺乏信任。
  • 我不能使用 MultithreadedTC ,至少我不知道,因为一个线程将始终执行,因此节拍器不会前进到下一个滴答声。
  • 我不想修改现有代码以添加仅用于测试目的的位。代码应避免添加来自测试的内容。
  • 我想要一些可靠的东西,我可以多次运行并用于回归测试。
  • 因为我不是唯一使用该代码的人,所以它应该是 Java 原生的,而不是使用 ConAn 等脚本语言。

这段代码足够小,我可以非常肯定地说它不会死锁或违反上面详述的条件。然而,一个好的测试用例可以增加它的权重,并且肯定会增加更多的信心。

最佳答案

这是一个测试气味的例子,可以说应该激发代码更改。代码很难测试,因为它在应用程序逻辑职责中混杂了同步职责。通常,很难确保此类代码正确运行。

最好将与同步相关的代码提取到一个单独的类中,该类本身是可测试的,并使用依赖注入(inject)来允许测试模拟该接口(interface)。

例如

public interface ResourceGuard<T> {
void accessResource(Consumer<T> consumer);
}

public class ExclusiveResourceGuard<T> implements ResourceGuard<T> {
private final T instance;
private final Semaphore semaphore;

public ExclusiveResourceGuard(final T instance) {
this.instance = instance;
}

public void accessResource(Consumer<T> consumer) {
semaphore.acquire();
consumer.consume(instance);
semaphore.release();
}
}

您现在可以通过传入一个作用于测试范围数据的假消费者来测试此类,并确保正确同步访问。

然后你的生产消费者类可以有一个注入(inject)的资源守卫......

public class StuffDoingClass {
private final ResourceGuard<MyThing> myThing;

public StuffDoingClass(final ResourceGuard<MyThing> theThing) {
this.myThing = theThing;
}

public void method() {
this.myThing.accessResource(this::doStuff);
}

private void doStuff(final MyThing theActualThing) {
theActualThing.method(...);
}
}

现在可以使用足够简单的 ResourceGuard 模拟来测试此类。

从设计的角度来看,错误地访问资源(不持有锁)也更加困难。我知道这个答案违背了您的“无代码更改”要求,但在这种特殊情况下,您似乎不太可能满足所有要求。

关于java - 在 Java 中测试简单的信号量使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21280652/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com