在某些情况下,即使是
的结果,线程也不会停止运行boolean cancel = future.cancel(true);
是真的。
如果我通过scheduleThread()
向scheduler
如果我致电schedule()
而不是scheduleThread()
,那么
if (scheduler != null) {
List<Runnable> shutdownNow = scheduler.shutdownNow();
}
scheduler = Executors.newScheduledThreadPool(elasticsearch2AWSs.size());
elasticsearch2AWSs.entrySet().forEach(entry -> scheduleThread(entry.getKey(), entry.getValue()));
创建scheduler
的新实例并调用scheduleThread()
创建一些线程,然后使用future.cancel(true);
取消它们一切正常。
但是当我想稍后添加一个线程时,我直接调用scheduleThread()
,线程按预期启动,我可以调用future.cancel(true);
来阻止它,结果是true
但是线程继续运行。我的第一个想法是,它与线程池大小有关,但在这种情况下似乎并不重要。
我在这里缺少什么?任何帮助表示赞赏!
处理线程的ConnectionScheduler
。
public final class ConnectionScheduler {
private ScheduledExecutorService scheduler;
private ConcurrentMap<String, ScheduledFuture<?>> futures = new ConcurrentHashMap<>();
public void schedule(Map<String, Elasticsearch2AWS> elasticsearch2AWSs) {
if (scheduler != null) {
List<Runnable> shutdownNow = scheduler.shutdownNow();
}
scheduler = Executors.newScheduledThreadPool(elasticsearch2AWSs.size());
// scheduler = Executors.newScheduledThreadPool(5); // test purposes
elasticsearch2AWSs.entrySet().forEach(entry -> scheduleThread(entry.getKey(), entry.getValue()));
}
public void scheduleThread(String key, Elasticsearch2AWS elasticsearch2AWS) {
Map<String, String> awsDimension = elasticsearch2AWS.getAws().get("dimension");
String dimensionValue = awsDimension.get("value");
long initialDelay = calcInitialDelay(elasticsearch2AWS.getElasticsearch().get("start"));
int interval = Integer.valueOf(elasticsearch2AWS.getElasticsearch().get("interval"));
logger.info("service: {} (start in {} sec and repeats every {} sec)", dimensionValue, initialDelay, interval);
Runnable task = () -> {
try {
logger.info("Runnable task service: {} (start in {} sec and repeats every {} sec)", dimensionValue, initialDelay, interval);
logger.info("Thread.currentThread().isInterrupted(): {}", Thread.currentThread().isInterrupted());
elasticConnector.startConnector(elasticsearch2AWS);
} catch (Exception ex) {
logger.error("Exception", ex);
}
};
futures.put(key, scheduler.scheduleAtFixedRate(task, initialDelay, interval, TimeUnit.SECONDS)); // filePath is our key
logger.info("futures '{}'", futures);
}
public void stopThread(String key) {
ScheduledFuture<?> future = futures.remove(key); // remove from our map
logger.info("stopping task '{}' {}", key, future);
boolean cancel = future.cancel(true); // cancel the thread
logger.info("cancel {}", cancel);
logger.info("futures '{}'", futures);
}
}
方法watchFolder()
在运行时检查修改的文件。如果文件已被修改,则通过connectionScheduler.scheduleThread(file.toString(), loadFile(file));
启动新线程,即使cancel
结果为真,如果取消呼叫,此线程也不会停止。
对于在程序启动时加载的监视文件夹内的现有文件,也会创建线程。此线程可以成功取消,如果我稍后在运行时创建线程,我不知道其中的差异。
public class PropertyReader {
...
public void init() {
readConfigPropertiesFile();
readElasticsearchFolder();
if (thread == null || !thread.isAlive()) {watchFolderThread();}
connectionScheduler.schedule(elasticsearch2AWSs);
}
private void watchFolder() {
try (final WatchService watchService = FileSystems.getDefault().newWatchService()) {
foldersToWatch.forEach(path -> path.register(watchService, StandardWatchEventKinds.ENTRY_CREATE, StandardWatchEventKinds.ENTRY_DELETE, StandardWatchEventKinds.ENTRY_MODIFY));
while (true) {
final WatchKey watchKey = watchService.take();
for (WatchEvent<?> event : watchKey.pollEvents()) {
final Path file = Paths.get(watchKey.watchable() + File.separator + (Path) event.context());
if (event.kind() == StandardWatchEventKinds.ENTRY_CREATE || event.kind() == StandardWatchEventKinds.ENTRY_MODIFY) {
logger.info("trigger reschedule of task: '{}'", file);
elasticsearch2AWSs.put(file.toString(), loadFile(file));
connectionScheduler.scheduleThread(file.toString(), loadFile(file));
//connectionScheduler.schedule(elasticsearch2AWSs);
}
if (event.kind() == StandardWatchEventKinds.ENTRY_DELETE) {
logger.info("remove task: '{}'", file);
connectionScheduler.stopThread(file.toString());
elasticsearch2AWSs.remove(file.toString());
// TODO remove from executer service
}
}
}
} catch (IOException ex) {
...
}
}
}
缩短代码以便更好地阅读