已清除的ScheduledFuture取消(true)仍然执行

时间:2018-05-15 18:19:29

标签: java multithreading model-view-controller concurrency runnable

我觉得我几乎阅读了有关ScheduledThreadPoolExecutor和ScheduledFutures及其取消的所有帖子。

基本上,我有一个ScheduledThreadPoolExecutor,池中有30个线程。我使用#schedule(Runnable,delay,TimeUnit)作为处理超时的方法来安排任务。 Runnable的占用空间非常小(使用值填充POJO,转换为JSON,并发送到我在已关闭网络中的服务器上设置的REST端点)。

public class MyObject {
  private String name;
  private ScheduledFuture<Void> future;

  public MyObject(String name) {
    this.name = name;
  }

  public String getName() {
    return this.name;
  }

  public ScheduledFuture<Void> getFuture() {
    return future;
  }

  public void setFuture(ScheduledFuture<Void> future) {
    this.future = future;
  }
}

public class TimeoutTask implements Runnable {
  @Override
  public void run() {
    // Build POST HTTP object

    // Send to server, receive response

    // No, I'm not catching any exceptions here (might be the issue)
  }
}

public class Util {
  private static final ScheduledThreadPoolExecutor SCHEDULER = new ScheduledThreadPoolExecutor(30);
  private static final HashMap<String, MyObject> OBJECTS = new HashMap<>();

  static {
    // Eject tasks from the queue upon cancellation
    SCHEDULER.setRemoveOnCancelPolicy(true);
    MyObject object1 = new MyObject("test");
    OBJECTS.put(object1.getName(), object1);

    MyObject object2 = new MyObject("test2");
    OBJECTS.put(object2.getName(), object2);

    MyObject object3 = new MyObject("test3");
    OBJECTS.put(object3.getName(), object3);
  }

  public static ScheduledFuture<Void> scheduleTask(int timeoutInSeconds){
    return SCHEDULER.schedule(new TimeoutTask(), timeoutInSeconds, TimeUnit.SECONDS);
  }

  public static void cancelTask(String name) {
    MyObject object = getObject(name);
    if (object != null){
      object.getFuture().cancel(true);
    }
  }

  public static MyObject getObject(String name) {
    return OBJECTS.get(name);
  }
}

@Controller
public class Controller {

  // REST BOILERPLATE
  @RequestMapping(...)
  public void receive(Message message) {
      if (message.getType().equals(MessageType.CANCEL)) {
          Util.cancelTask(message.getObjectName());
      }
  }
}

@Component
public class View {

  @PostConstruct
  public void init() {
    JFrame frame = new JFrame();
    JPanel panel = new JPanel();
    JButton button = new JButton("Do Something");
    button.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        Util.getObject("test").setFuture(Util.scheduleTask(5));
        Util.getObject("test1").setFuture(Util.scheduleTask(15));
        Util.getObject("test2").setFuture(Util.scheduleTask(60));
      }
    });
    panel.add(button);
    frame.add(panel);
    frame.pack
    frame.setVisible(true);
  }
}

我使用true取消ScheduledFuture以允许执行中断,我在之前和之后评估队列以查看它是否被弹出并且它是但在延迟完成后任务仍然运行

这里的任何帮助都会很棒。这个例子非常简单,但我至少想表明我使用Spring,在一个常见的Util类中引用超时(所以我的引用并没有混淆),而且这显然是多线程的MVC模式,控制器可以接收大量消息并假脱机处理这些消息的接收,如果消息类型正确,可能导致取消期货。

0 个答案:

没有答案