等待/通知共享对象导致主线程挂起

时间:2015-04-24 07:34:38

标签: java multithreading quartz-scheduler


  首先让我承认我是一位经验丰富的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这样的类

任何指针都会有很大帮助。

谢谢,
稻谷

0 个答案:

没有答案
相关问题