Мне кажется, что я прочитал почти каждый пост на SO о 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);
}
}
Я отменяю ScheduledFuture, используяЗначение true, чтобы разрешить прерывание выполнения, и я оценил очередь до и после, чтобы увидеть, будет ли она извлечена, и это так, но задача все еще выполняется после того, как задержка завершит .
Любая помощь здесь будет потрясающей.Этот пример очень сокращен, но я по крайней мере хотел показать, что я использую Spring, ссылаясь на тайм-ауты в общем классе Util (поэтому мои ссылки не перепутываются), и что это, очевидно, многопоточный шаблон MVC, гдеКонтроллер может получать множество сообщений и распределять несколько потоков для обработки этих сообщений, что может привести к отмене фьючерса, если тип сообщения правильный.