3

乱数をリ​​ッスンするプログラムがあります。それは私に番号と新しいカウントを与えるパブリッシャーに接続されており、更新を取得するたびに、その番号の現在のカウントを HashMap に保存しています。

リクエストをリッスンするSSLサーバーもあります。「7 はいくつありますか」という要求があった場合、私は HashMap で値を返すだけです。

ここで、その数が 0 回発生した場合は、1 回発生するまで待機し、その時点でのカウントを返すというロジックを追加します。ただし、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 ステートメントを入れることはできません。では、これはどのように行うのが最善でしょうか?

ありがとうございました!

4

2 に答える 2

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 に答える
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 に答える