0

StackOverflowの助けを借りた後、私は以下に実装したソリューションを見つけました。

問題文:-

各スレッドはUNIQUE ID毎回使用する必要があり、60 minutesそれ以上実行する必要があるため60 minutes、すべてID'sが終了する可能性があるため、それらを再利用する必要がありID'sます。だから私はArrayBlockingQueueここでコンセプトを使用しています。

2つのシナリオ:-

  1. command.getDataCriteria()が含まれている場合、Previous各スレッドは常にUNIQUE ID間で使用1 and 1000し、再利用するために解放する必要があります。
  2. それ以外の場合、command.getDataCriteria()が含まれている場合、New各スレッドは常にUNIQUE ID間で使用2000 and 3000し、再利用するために解放する必要があります。

質問:-

私が今気づいた奇妙なことの1つは、以下のelse ifループで、runメソッドに以下のコードが表示されている場合、command.getDataCriteria() is Previousそれが入力されてelse if block(which is for New)いること.equals checkです。なぜこれが起こっているのですか?

else if(command.getDataCriteria().equals(PDSLnPConstants.DATA_CRITERIA_NEW)) {

以下は私のコードです:-

class ThreadNewTask implements Runnable {
      private Command command;
      private BlockingQueue<Integer> existPool;
      private BlockingQueue<Integer> newPool;
      private int existId;
      private int newId;


      public ThreadNewTask(Command command, BlockingQueue<Integer> pool1, BlockingQueue<Integer> pool2) {
            this.command = command;
            this.existPool = pool1;
            this.newPool = pool2;
      }

      public void run() {

            if(command.getDataCriteria().equals(PDSLnPConstants.DATA_CRITERIA_PREVIOUS)) {
                  try {
                        existId = existPool.take();
                        someMethod(existId);
                  } catch (Exception e) {
                        System.out.println(e);
                  } finally {
                        existPool.offer(existId);
                  }
            } else if(command.getDataCriteria().equals(PDSLnPConstants.DATA_CRITERIA_NEW)) {
                  try {
                        newId = newPool.take();
                        someMethod(newId);
                  } catch (Exception e) {
                        System.out.println(e);
                  } finally {
                        newPool.offer(newId);
                  }
            }
      }

      // And this method needs to be synchronized or not?
      private synchronized void someMethod(int i) {
            System.out.println();
            System.out.println("#####################");
            System.out.println("Task ID: " +i);
            System.out.println("#####################");
            System.out.println();
      }
}

public class TestingPool {
      public static void main(String[] args) throws InterruptedException {
            int size = 10;
            int durationOfRun = 60;
            LinkedList<Integer> availableExistingIds = new LinkedList<Integer>();
            LinkedList<Integer> availableNewIds = new LinkedList<Integer>();
            for (int i = 1; i <= 1000; i++) {
                  availableExistingIds.add(i);
            }
            for (int i = 2000; i <= 3000; i++) {
                  availableNewIds.add(i);
            }
            BlockingQueue<Integer> existIdPool = new ArrayBlockingQueue<Integer>(1000, false, availableExistingIds);
            BlockingQueue<Integer> newIdPool = new ArrayBlockingQueue<Integer>(1000, false, availableNewIds);

            // create thread pool with given size
            ExecutorService service = new ThreadPoolExecutor(size, size, 500L, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10), new ThreadPoolExecutor.CallerRunsPolicy()); 


            // queue some tasks
            long startTime = System.currentTimeMillis();
            long endTime = startTime + (durationOfRun * 60 * 1000L);

            // Running it for 60 minutes
            while(System.currentTimeMillis() <= endTime) {
                  Command nextCommand = getNextCommandToExecute();
                  service.submit(new ThreadNewTask(nextCommand, existIdPool, newIdPool));
            }

            // wait for termination        
            service.shutdown();
            service.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS); 
      }
}

アップデート:-

私が今気づいた奇妙なことの1つは、以下のelse if loop場合、command is Previousそれが正しく発生してはならない他のifブロックにも入力されているということです。なぜこれが起こっているのですか?なぜこのようなことが起こっているのか分かりませんか?

else if(command.getDataCriteria().equals(PDSLnPConstants.DATA_CRITERIA_NEW)) {
4

1 に答える 1

1

if ()あなたが入力した場合、あなたも入力する方法がないelseので、何か他のことが起こっています。コードに問題はないので、出力を誤って解釈しているのではないかと思います。あなたは別のCommandものが来ることを期待していますgetNextCommandToExecute()か?

Commandランダムを設定しdataCriteriaて次の出力を取得するシミュレーションを使用してコードを実行しました。私はそれで何も悪いことはわかりません:

Task ID: 2001
Task ID: 1
Task ID: 2002
Task ID: 2003
Task ID: 2
Task ID: 2004
Task ID: 3
Task ID: 2005
...

スレッドに特定のタイミングを期待していますか?スレッドの競合状態を考えると、最初にCommand生成されたものが必ずしも最初に表示される出力であるとは限りません。

コードに関する一般的なフィードバックは次のとおりです。

  • pool.put(...)代わりにを使用するとoffer(...)、が返されfalseます。
  • キューをロードするのではなく、作成後にキューを埋めた方がよいでしょうLinkedList
  • ArrayList通常の代わりに使用する必要がありますLinkedList
  • ロードしfor (int i = 2000; i <= 3000; i++)ますが、2001から3000までである必要があります。そうでない場合は、1000を超える数値になります。
于 2012-10-18T14:04:59.957 に答える