我有一个正在收听随机数的程序。它连接到一个发布者,它给我一个数字和一个新的计数,每次我得到更新时,我都将该数字的当前计数存储在HashMap中。
我还有一个SSL服务器正在侦听请求。当一个请求询问“我们有多少7个”时,我只返回我的HashMap中的值。
现在我想添加逻辑,如果我们有0次出现这个数字,请等到我们得到一个,然后返回那个点的计数。然而,由于Thread的run方法的限制,我正在努力,它必须是一个空白。我想知道是否有任何方式只是声明我的方法总是启动一个新线程,或者可能是一个比我正在做的更好的方法来处理它。这就是我所拥有的:
private static volatile HashMap<Integer, Integer> occurenceMap= new HashMap<Integer, Integer>();
public synchronized static int getNumOccurrences(final Integer number) {
try {
(new Thread() {
public void run() {
Integer occurrences = occurenceMap.get(number);
if ( occurrences != null && occurrences > 0 ) {
// here I would like to just return occurences;
} else {
CountDownLatch latch = new CountDownLatch(1);
pendingList.put(number, latch);
latch.await();
// elsewhere in the code, I call countdown when I get a hit
pendingList.remove(number);
// once we've counted down, I would like to return the value
}
}
}).start();
} catch ( Throwable t ) { }
}
但是,我不能在run方法中放置return语句。那怎么做得最好呢?
谢谢!
答案 0 :(得分:0)
您需要某种外部结构来存储号码,例如
// declared outside your runnable
final AtomicInteger result = new AtomicInteger(0);
// in your run method
// return value; // doesn't work, can't return
result.set(value);
因此,将其添加到您的
中请注意,我的评论以// C:
private static volatile HashMap<Integer, Integer> occurenceMap= new HashMap<Integer, Integer>();
public synchronized static int getNumOccurrences(final Integer number) {
// C: here's a container to use inside the runnable
// C: must be final to use inside the runnable below
final AtomicInteger result = new AtomicInteger(0);
try {
// C: keep a rerefence to the thread we create
Thread thread = new Thread() {
public void run() {
Integer occurrences = occurenceMap.get(number);
if ( occurrences != null && occurrences > 0 ) {
result.set(occurences); // C: we found what we're looking for
return; // C: so get out of the run method
} else {
CountDownLatch latch = new CountDownLatch(1);
pendingList.put(number, latch);
latch.await();
// elsewhere in the code, I call countdown when I get a hit
pendingList.remove(number);
// once we've counted down, I would like to return the value
result.set(1); // C: I'm not sure what you want to return here
return; // C: but I'm sure you can figure that out...
}
}
});
thread.start(); // C: now start the thread
thread.join(); // C: join the thread, waiting for it to finish
} catch ( Throwable t ) { }
return result.get(); // C: now return the int from the container
}
答案 1 :(得分:0)
从Thread
执行结果值的另一种方法是使用Executors
线程池,它允许您提交Callable
:
// create a thread pool with 10 workers
ExecutorService threadPool = Executors.newFixedThreadPool(10);
List<Future<Integer>> futures = new ArrayList<Future<Integer>>();
for (Job job : jobsToDo) {
futures.add(threadPool.submit(new Callable<Integer>() {
public Integer call() {
...
}
}));
}
// after submitting the jobs, you need to shutdown the queue
threadPool.shutdown();
// then you can get the results
for (Future<Integer> future : futures) {
// this will throw if your call method throws
int value = future.get();
}