0

在从 StackOverflow 获得帮助后,我找到了我在下面实现的解决方案。

问题陈述:-

每个线程每次都需要使用UNIQUE ID,并且必须运行60 minutes或更长时间,因此60 minutes有可能所有线程都ID's将完成,因此我需要ID's再次重用它们。所以我在ArrayBlockingQueue这里使用概念。

两种情况:-

  1. 如果command.getDataCriteria()包含Previous,那么每个线程总是需要在UNIQUE ID之间使用1 and 1000并释放它以再次重用。
  2. 否则,如果command.getDataCriteria()包含New,那么每个线程总是需要在UNIQUE ID之间使用2000 and 3000并释放它以再次重用。

问题:-

我刚刚注意到的一件奇怪的事情是 - 在下面的 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); 
      }
}

更新:-

我刚刚注意到的一件奇怪的事情是 - 在下面的else if loopif command is Previousthen 中,它也被输入到 else 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(...)which could return false
  • 您最好在构建队列后填充队列,而不是使用LinkedList.
  • 你应该使用ArrayList而不是LinkedList通常。
  • 您加载,for (int i = 2000; i <= 3000; i++)但需要从 2001 到 3000,否则它将超过 1000 个数字。
于 2012-10-18T14:04:59.957 回答