首先让我承认我是一位经验丰富的Java开发人员,他们知道等待/通知问题,但是没有得到线索,这就是为什么当我们陷入困境并且忽略了明显的事情时,人们的更多输入会有所帮助的原因。我正在编写一个测试来验证Quartz作业类,我按照以下方式进行操作(示例):
public class SchedulerTest {
private static final Object LOCK = new Object();
@Test
public void shouldValidateSomethingInJob() {
Object[] paramsForTesting = ...
SchedulerFactory sf = new StdSchedulerFactory();
Scheduler scheduler = sf.getScheduler();
...
CustomJobListenerSupport jobListener =
new CustomJobListenerSupport(LOCK, paramsForTesting);
scheduler.getListenerManager().addJobListener(jobListener,
KeyMatcher.keyEquals(jobKey));
scheduler.start();
// synchronized (LOCK) {
// // Wait for scheduler to end to avoid DB rollback before that
// LOCK.wait();
// }
}
private static class CustomJobListenerSupport extends JobListenerSupport
{
private final Object lock;
public CustomJobListenerSupport(Object lock, Object ... paramsForTesting) {
...;
this.lock = lock;
}
@Override
public String getName() {
return "TestJobListener";
}
@Override
public void jobWasExecuted(JobExecutionContext context,
JobExecutionException jobException) {
if (isNotBlank(jobException.getMessage())) {
try {
cleanup(context.getScheduler());
} catch (SchedulerException e) {
logger.error(e);
}
throw new RuntimeException(jobException);
}
performAssertions();
try {
cleanup(context.getScheduler());
} catch (SchedulerException e) {
throw new RuntimeException(e);
}
}
private void performAssertions() {
// Some assertions
}
@SneakyThrows
private void cleanup(Scheduler scheduler) throws SchedulerException {
scheduler.clear();
scheduler.shutdown();
System.out.println("\nLock in cleanup: "+lock);
synchronized (lock) {
lock.notify();
}
}
}
}
现在等待代码已注释掉,测试完成但失败,因为数据库更改在调度程序完成之前回滚,而如果我把等待主线程似乎挂起(至少花了很长时间并且似乎没有结束)我无法弄清楚作业是否仍在运行,因为Junit没有编写包含日志语句的HTML报告。调试语句表明这两个类都使用相同的LOCK对象。同意有比使用普通对象锁定更好的选择,但是想稍后再尝试,因为我不熟悉像ReentrantLock
这样的类
任何指针都会有很大帮助。
谢谢,
稻谷