3

我有一个正在监听随机数的程序。它连接到一个发布者,它给了我一个数字和一个新的计数,每次我得到更新时,我都会将该数字的当前计数存储在 HashMap 中。

我还有一个监听请求的 SSL 服务器。当一个请求询问“我们有多少个 7”时,我只返回我的 HashMap 中的值。

现在我想添加一个逻辑,如果我们有 0 次出现该数字,请等到我们得到 1 次,然后返回该点的计数。但是,由于 Thread 的 run 方法的限制,我正在挣扎,它必须是一个 void。我想知道是否有任何方法可以将我的方法声明为始终启动新线程的方法,或者可能是比我正在做的更好的处理方法。这是我所拥有的:

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 ) { }
}

但是,我不能将 return 语句放在 run 方法中。那么如何做到最好呢?

谢谢!

4

2 回答 2

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
    }
于 2012-11-21T20:46:46.947 回答
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();
}
于 2012-11-21T21:25:37.487 回答