我有一个任务队列和一个线程,在几秒钟内窥探一次队列,并且它有一个任务执行它。等待未知数量的异步任务
我有另一个代码段(当然是另一个线程),它在循环中创建任务(我无法预先从循环外部知道任务数量)并将它们插入到队列中。任务包含一些“结果”对象,外部线程(创建这些任务)需要等待所有任务完成并最终从每个任务中获取结果。 问题是我无法将java Semaphore \ CountDownLatch等传递给结果对象,因为我不知道提前显示器的数量。 我也不能使用使用invokeAll的Executor,或者等待Future对象,因为任务是不同步的(外部线程只是将任务加入到队列中,而另一个线程在他有空时执行任务)。
我唯一想到的解决方案是创建一些“反转信号量”类,它包含一组结果和一个监视器计数器。该功能的getResult将检查计数器== 0,如果答案是肯定就会通知一些锁定的对象,以及功能的getResult会等待这个锁:
public class InvertedSemaphore<T> {
Set<T> resultSet;
int usages;
final Object c;
public InvertedSemaphore() {
resultSet = Collections.synchronizedSet(new HashSet<T>());
usages = 0;
c = new Object();
}
public void addResult(T result) {
resultSet.add(result);
}
public void addResults(Set<T> result) {
resultSet.addAll(result);
}
public void acquire() {
usages++;
}
public void release() {
synchronized (c) {
if (--usages == 0) {
c.notify();
}
}
}
public Set<T> getResults() {
synchronized (c) {
try {
while (usages > 0) {
c.wait();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return resultSet;
}
}
每个addTask方法调用semaphore.acquire,和每个(未同步)任务将在任务结束时调用semaphore.release。
这听起来很复杂,我很确定在java并发库中有更好的解决方案。
任何想法将appriciated :)
听起来像你需要'CountUpLatch'。:) – corsiKa 2012-07-25 17:17:53