我有一个用例,我不断测试工作流程。我有一个mysql数据库的条目来存储学生记录,检索它,用一些细节更新它,然后最后删除它。
为了测试这些工作流程,我将每个步骤作为单独的方法。现在,为了连续测试它,我可能正在考虑让整个工作流程在多线程模型中执行。
我遇到的困难是我如何让其他操作(获取,更新和删除)等到创建操作完成。我正在查找Thread.join()并通知方法,但我不确定这是否是最优雅的方式。
以下是我目前的代码示例(相当天真的版本):
public class Test {
public static void main(String[] args) {
while (true) {
String studentId = createStudent();
Thread.sleep(1000);
Runnable calls[] = new Runnable {
() -> getStudent(studentId),
() -> updateStudent(studentId),
() -> delete(studentId)
};
for (Runnable call: calls) {
call.run();
}
}
}
private String createStudent() {
...
...
...
return studentId;
}
private void getStudent(String studentId)
...
...
...
}
private void updateStudent(String studentId)
...
...
...
}
private void deleteStudent(String studentId)
...
...
...
}
}
我很确定我介绍睡眠的方式是一个非常天真的实现,绝对不推荐。如果我不得不使用通知或加入,是否有最佳实践建议我可以查找?
答案 0 :(得分:0)
这可以通过线程等待和通知线程通信方式或使用倒计时锁存来解决。下面的例子说明倒计时锁存方式。
public class ConditionAwaiter {
private final Callable<Boolean> asyncCondition;
private final Condition condition;
private final CountDownLatch latch;
private Throwable throwable = null;
public ConditionAwaiter(Callable<Boolean> asyncCondition, Condition condition) {
this.asyncCondition = asyncCondition;
this.condition = condition;
this.latch = new CountDownLatch(1);
}
public void await() {
boolean processCompleted = false;
try {
new WaitThread(asyncCondition, condition).start();
Duration maxWaitTime = condition.getWaitDuration();
if (maxWaitTime.getValue() == WaitStrategy.WAIT_FOREVER) {
latch.await();
processCompleted = true;
} else {
processCompleted = latch.await(maxWaitTime.getValue(), maxWaitTime.getTimeUnit());
}
} catch (Exception e) {
throwable = e;
} finally {
if (throwable != null || !processCompleted) {
throw new IllegalStateException("Not able to complete on time");
}
}
}
class WaitThread extends Thread {
private final Callable<Boolean> asyncCondition;
private final Condition condition;
private Duration pollInterval;
private Lock lock = new ReentrantLock();
private java.util.concurrent.locks.Condition lockCondition = lock.newCondition();
public WaitThread(Callable<Boolean> asyncCondition, Condition condition) {
this.asyncCondition = asyncCondition;
this.condition = condition;
pollInterval = condition.getPollInterval();
}
@Override
public void run() {
lock.lock();
try {
try {
while (!asyncCondition.call()) {
lockCondition.await(pollInterval.getValue(), pollInterval.getTimeUnit());
}
} catch (InterruptedException e) {
}
if (asyncCondition.call()) {
latch.countDown();
}
} catch (Exception e) {
throwable = e;
} finally {
lock.unlock();
}
}
}
}