Future.cancel()方法中的问题

时间:2015-10-05 09:29:44

标签: java multithreading

我有一个以下可运行的任务,它使用<int:inbound-channel-adapter channel="quakeinfotrigger.channel" expression="''"> <int:poller fixed-delay="60000"></int:poller> </int:inbound-channel-adapter> <int:channel id="quakeinfo.channel"> <int:queue capacity="10" /> </int:channel> <int:channel id="quakeinfotrigger.channel"></int:channel> <int:channel id="error.channel"> <int:queue capacity="10" /> </int:channel> <int:service-activator input-channel="error.channel" ref="httpResponseErrorHandler" method="handleMessage"> <int:poller fixed-delay="5000"></int:poller> </int:service-activator> <int:service-activator input-channel="quakeinfo.channel" ref="httpResponseMessageHandler" method="handleMessage"> <int:poller fixed-delay="5000"></int:poller> </int:service-activator> <int:gateway id="requestGateway" service-interface="standalone.HttpRequestGateway" default-request-channel="quakeinfotrigger.channel" error-channel="error.channel" /> <int-http:outbound-gateway id="quakerHttpGateway" request-channel="quakeinfotrigger.channel" url="http://fooo/mmmm/rest/put/44545454" http-method="PUT" expected-response-type="java.lang.String" charset="UTF-8" reply-timeout="5000" reply-channel="quakeinfo.channel"> </int-http:outbound-gateway> <bean id="httpResponseMessageHandler" class="standalone.HttpResponseMessageHandler" /> <bean id="httpResponseErrorHandler" class="standalone.HttpResponseErrorHandler" /> 运行。这可以确保队列中只有一个等待任务。

ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(1));

考虑来电者A:

protected void waitAndSweep(final String symbol) {
    try { 

        runnable = new Runnable() {
          @Override
          public void run() {
            try {
             // long sweepTime = symbolInfo.getSweepTime(symbol);
              // long timeSinceLastSweep = System.currentTimeMillis() - lastSliceSentTime;
              boolean sliceDone = Quant.equals(wave.getCommitedQuantity() % getSliceQuantity(),0);
              if(sliceDone){
                long timeSinceLastSliceQtySent = lastSliceSentTime == 0 ? getInterval() : System.currentTimeMillis() - lastSliceSentTime;
                long waitTime = timeSinceLastSliceQtySent >= getInterval() ? 0 : getInterval() - timeSinceLastSliceQtySent;
                logTradeEvent("waitAndSweep", symbol, "waittime: " + waitTime);
                if (waitTime > 0){
                  Thread.sleep(waitTime);
                }
              }

              callSweep(symbol);
            } catch(InterruptedException ie){
              ie.printStackTrace();
            }
            catch (Exception e) {
              logEvent(StrategyEntry.ERROR, "waitAndSweep", symbol,
                  "Exception caught...", e);
            }            
          }
        };

      self = threadPoolExecutor.submit(runnable);   
    }catch(RejectedExecutionException re){
      /* this exception will be thrown when wait and sweep is called more than twice.
       * threadPoolExecutor can have one running task and one waiting task.
       * */
      System.out.print(re);
      }catch (Exception e) {
      logEvent(StrategyEntry.ERROR, "waitAndSweep", symbol,
          "Exception caught...", e);
    }
  }

这个疯狂的两个任务将运行,另一个在队列中等待。

考虑来电者:

private void callerA(){
waitandsweep();
waitandsweep();}

期望callerB取消A调用的所有任务。 实际上它没有发生..调用者B调用的任务被拒绝,因为已经有一个任务在队列中等待。你能告诉我为什么会出现这种情况吗?

编辑1:如何取消执行程序的运行任务?

1 个答案:

答案 0 :(得分:3)

问题是,Future.cancel(boolean)不会从队列中删除任务。一旦它被Executor拉出,但在此之前它仍然在队列中,该任务将不会被执行

尝试在threadPoolExecutor.purge();之后立即使用cancel();,它会尝试删除已取消的任务

取消正在运行的任务并不容易,您可以尝试以下操作: 致电cancel(true);,它会将Thread.interrupted()设为true。现在,在您的任务中检查一些有价值的步骤,以便您可以决定跳过任务的后续步骤