使用线程的中断状态终止循环。这比您创建自己的标志更好,因为它使您的任务可与一起使用
ExecutorService;您可以通过
Future提交时收到的特定任务取消特定任务,也可以使用中断所有任务
shutdownNow()。
除非您的任务在创建和管理的线程中运行,否则在检测到中断后重新声明中断状态是最安全的,以便调用者也可以处理它。换句话说,所有线程和任务都必须具有定义的中断策略并相应地使用。
例这是使用的示例
Runnable任务
WatchService:
final class FileWatch implements Runnable { private final WatchService watcher; FileWatch(WatchService watcher) { this.watcher = watcher; } @Override public void run() { while (!Thread.currentThread().isInterrupted()) { WatchKey key; try { key = watcher.take(); } catch (InterruptedException ex) { Thread.currentThread().interrupt(); break; } Watchable dir = key.watchable(); System.out.println(dir); for (WatchEvent<?> evt : key.pollEvents()) { System.out.println(" " + evt.context()); } } }}
使用这种服务的方法如下:
public static void main(String... argv) throws Exception{ Path home = Paths.get(System.getProperty("user.home")); WatchService watcher = home.getFileSystem().newWatchService(); home.register(watcher, StandardWatchEventKinds.ENTRY_CREATE, StandardWatchEventKinds.OVERFLOW); Runnable task = new FileWatch(watcher); ExecutorService exec = Executors.newCachedThreadPool(); exec.submit(task); Thread.sleep(3000); exec.shutdownNow(); boolean terminated = exec.awaitTermination(1, TimeUnit.SECONDS); if (terminated) System.out.println("All tasks completed."); else System.out.println("Some tasks are still running.");}
由于
FileWatch任务正确支持中断,因此您将看到此测试显示
shutdownNow()调用后不久所有任务都已完成。如果您将使用其他终止方法的任务添加到中
ExecutorService,则会看到它们继续运行。有问题的代码
目前的代码存在两个问题。这是
jToggleButton1ActionPerformed()事件处理程序的分析,按下按钮时,该事件处理程序由Swing事件调度线程(
EDT )调用。
当按下按钮时, 创建一个新的ExecutorService作为局部变量。 如果选择切换, 向执行者提交文件监视任务,以及 阻塞EDT 1秒钟,或者直到执行程序关闭。 除此以外, 关闭新创建的执行程序。 放弃对执行程序的引用。
第一个问题是,由于执行程序服务永远不会存储在局部变量之外的任何地方,因此一旦该方法退出,对该特定实例的引用将永远丢失,并且无法对其进行调用
shutdownNow()。
第二个问题是,如果确实要阻止EDT(可能不是一个好主意)直到执行程序终止,则应在调用之后
shutdownNow()(在“
else”子句中,未选中toggle时)执行此 *** 作,而不是在提交任务之后执行。再次查看上面的示例,您将看到我仅在关闭执行程序后才等待终止。
将ExecutorService变量从方法中吊起,并使其成为类的成员变量。这将允许切换按钮处理程序访问 同一个实例
的
ExecutorService,并关闭它。然后,将等待终止移至未选择的切换分支。
这是应该的流程:
当按下按钮时, 如果选择切换, 创建一个新的执行程序服务并将其分配给成员变量,然后 向服务提交文件监视任务。 除此以外, 关闭执行程序,并 等待服务终止。
另外,只要您在这里使用,a
newSingleThreadedExecutor()就足够了。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)