我們試圖實現一種我們的應用程序的多線程部分和數據庫訪問之間ensurance,使DB不會有太多的線程被擊中(客戶要求時保持活着),同時使系統的其他部分充分利用必要的線程數量。智能方式ThreadPoolTaskExecutor類測試
設計似乎工作(春天批處理分區+使用ThreadPoolTaskExecutor處理數據訪問),但問題是與測試設計(基於http://helenaedelson.com/?p=432)。
現在我必須將Thread.sleep(4000)添加到我的單元測試中,以確保在產生的額外線程有變化完成工作之前,Spring上下文不會從測試下被終止並且返回值返回到主線程。
會有人對如何使這個測試implementastion更聰明一些更好的想法嗎?
測試儀:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({ "classpath:partitionJdbcJob.xml" })
@DirtiesContext(classMode = ClassMode.AFTER_CLASS)
public class TaskTests {
protected static final Logger logger = LoggerFactory.getLogger(TaskTests.class);
@Autowired
private OrderServiceImpl orderService;
@Test
public void testExecution() {
logger.info("Starting execution thread...");
for (int i = 0; i < 8; i++) {
orderService.dispatch();
}
try {
// So that spring context is not destroyed from under the multi-threaded runnables
Thread.sleep(4000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
測試服:
@Service("orderServiceImpl")
public class OrderServiceImpl {
protected static final Logger logger = LoggerFactory.getLogger(OrderServiceImpl.class);
@Resource(name = "beanTaskExecutor")
private TaskExecutor taskExecutor;
// private AsyncTaskExecutor taskExecutor;
CompletionService completionService;
@Autowired
public void OrderServiceImpl(DataSource dataSource) {
completionService = new ExecutorCompletionService(taskExecutor);
}
public void dispatch(final RetailPriceOptimization order) {
logger.info("Starting dispatch execution...");
if (this.taskExecutor != null) {
logger.info("taskExecutor found...");
this.taskExecutor.execute(new Runnable() {
public void run() {
withExecutor(order);
}
});
}
try {
Object future1 = completionService.take().get();
Object future2 = completionService.take().get();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
logger.info("Completed dispatch execution...");
}
private void withExecutor(final RetailPriceOptimization order) {
logger.info("Starting withExecutor execution...");
Object result1 = completionService.submit(new Callable<String>() {
public String call() {
return findById("0000dd2gsl1u1546");
}
});
Object result2 = completionService.submit(new Callable() {
public Object call() {
return orderDao.find(new Long("16"));
}
});
}
}