有没有办法将方法声明为Java中的新线程

时间:2012-11-21 20:44:38

标签: java multithreading countdownlatch

我有一个正在收听随机数的程序。它连接到一个发布者,它给我一个数字和一个新的计数,每次我得到更新时,我都将该数字的当前计数存储在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语句。那怎么做得最好呢?

谢谢!

2 个答案:

答案 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();
}