我有此代码,可以正常工作。这个问题的重点是代码的可维护性,减少编写代码即可实现相同的目标:
Queue<IncomingItem[]> queue = new ConcurrentLinkedQueue<>();
IncomingItem[] EOF = new IncomingItem[0];
ForkJoinPool.commonPool().submit(() -> {
IncomingItem[] next;
while((next = queue.poll()) != EOF) {
if(next == null) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
continue;
}
dao.batchInsert(next);
}
});
ds.reload(queue::add);
queue.add(EOF);
ForkJoinPool.commonPool().awaitQuiescence(1, TimeUnit.HOURS);
目的是使ds.reload
(这是一个多线程方法)的输出被馈送到dao.batchInsert
方法中,该方法是非线程安全的,非线程共享的(例如,一个基于Hibernate的DAO),而不会阻塞ds.reload
方法,就像将dao.batchInsert
方法设为synchronized
一样。
此代码与Java 8兼容。较新的Java版本中有什么可以实现更优雅的解决方案的东西吗?
答案 0 :(得分:1)
在这里使用线程池是不必要的麻烦。使用专用线程。与其轮询和休眠,不如使用阻塞队列。
BlockingQueue<IncomingItem[]> queue = new LinkedBlockingQueue<>();
IncomingItem[] EOF = new IncomingItem[0];
Thread thread = new Thread(() -> {
IncomingItem[] next;
while((next = queue.take()) != EOF) {
dao.batchInsert(next);
}
});
thread.start();
ds.reload(queue::put);
queue.add(EOF);
thread.join();