Java 如何终止检测新文件的连续线程
这是我第一次涉足WatchService和多线程 我有一个应用程序,需要在外部设备发出提示让用户做某事时进行检测。提示通过放入特定文件夹中的XML文件传递。该文件的标题始终为“PRM.xml”,并将覆盖以前的PRM文件(如果存在)。为了防止重新显示旧的提示,“我的代码”会在显示后删除PRM文件 应用程序是用户交互的,因此当用户在主线程上执行其他活动时,它总是在后台线程中侦听PRM.xml 问题是,当用户希望在主线程中结束会话时(通过键入sentinel“zzz”),侦听线程不会结束,并且应用程序只有在被监视的文件夹中发生另一个事件时才会终止 当用户指示主线程终止时,如何强制后台侦听线程退出?(我希望我包含了足够的代码以获得良好的响应。)Java 如何终止检测新文件的连续线程,java,multithreading,watchservice,Java,Multithreading,Watchservice,这是我第一次涉足WatchService和多线程 我有一个应用程序,需要在外部设备发出提示让用户做某事时进行检测。提示通过放入特定文件夹中的XML文件传递。该文件的标题始终为“PRM.xml”,并将覆盖以前的PRM文件(如果存在)。为了防止重新显示旧的提示,“我的代码”会在显示后删除PRM文件 应用程序是用户交互的,因此当用户在主线程上执行其他活动时,它总是在后台线程中侦听PRM.xml 问题是,当用户希望在主线程中结束会话时(通过键入sentinel“zzz”),侦听线程不会结束,并且应用程序
//方法“run”包含要在线程中执行的代码
公开募捐{
试一试{
//启动新的监视服务以监视新的提示
WatchService ws=dirToWatch.getFileSystem().newWatchService();
dirToWatch.register(ws,ENTRY\u CREATE);
//持续监视目录,直到主程序线程结束
而(!SmartTill.stCom.equals(“ZZZ”)){
//获取新目录事件
WatchKey wk=ws.take();
//循环遍历所有检索到的事件
for(WatchEvent事件:wk.pollEvents()){
if(event.context().toString().endsWith(fileToDetect)){
System.out.println(“调试:显示提示,删除PRM”);
//…对“displayPrompt”方法的调用转到此处。。。
delFile(path.get(dirToWatch+fileToDetect));
}//如果结束
}//结束
//重置按键(清除事件列表)
System.out.println(“键已被”+
(wk.reset()?“reset.”:“unregistered.”);
}//结束时
}//结束尝试
捕获(例外e){}
}//终点
尝试向主线程添加关机挂钩,这样当主应用程序退出时,您也可以正确终止侦听线程
要做的更改
根据您的代码,需要进行以下更改:
public void stopThread() {
try {
System.out.println("closing the ws");
ws.close();
} catch (IOException e) {
e.printStackTrace();
}
}
2.在应用程序关闭时关闭WatchService
在主线程中,添加一个shutdown钩子,这样当应用程序关闭时,它将调用侦听线程类的stopThread()
方法
Runtime.getRuntime().addShutdownHook(new Thread(new Runnable(listenThreadObj) {
public void run() {
listenThreadObj.stopThread();
}
}));
示例代码
监听线程
当主线程关闭时,它将运行ShutdownCleaner线程。尝试向主线程添加关闭挂钩,以便在主应用程序退出时,您也可以正确终止侦听线程 要做的更改 根据您的代码,需要进行以下更改:
public void stopThread() {
try {
System.out.println("closing the ws");
ws.close();
} catch (IOException e) {
e.printStackTrace();
}
}
2.在应用程序关闭时关闭WatchService
在主线程中,添加一个shutdown钩子,这样当应用程序关闭时,它将调用侦听线程类的stopThread()
方法
Runtime.getRuntime().addShutdownHook(new Thread(new Runnable(listenThreadObj) {
public void run() {
listenThreadObj.stopThread();
}
}));
示例代码
监听线程
当主线程关闭时,它将运行ShutdownCleaner线程
当用户指示主线程终止时,如何强制后台侦听线程退出
你应该中断线程。WatchService.take()
方法抛出InterruptedException
。这意味着当主线程完成时,它可以中断watch服务线程。这将导致take()
方法抛出一个InterruptedException
,使监视线程有机会清理并退出while
循环,然后从run()
方法返回
Thread watchThread = new Thread(new WatchRunnable());
watchThread.start();
// ...
// when the main thread wants the program to stop, it just interrupts the thread
watchThread.interrupt();
// although not necessary, main thread may wait for the watch-thread to finish
watchThread.join();
当捕捉到中断异常时,重新中断线程始终是一个好模式,以便调用者也可以使用中断状态:
WatchKey wk;
try {
wk = ws.take();
} catch (InterruptedException ie) {
// always recommended
Thread.currentThread().interrupt();
// leave the loop or maybe return from run()
break;
}
重要的是要注意,中断线程并不是什么神奇的调用。它在线程上设置一个中断标志,该标志导致显式抛出InterruptedException
的某些方法抛出。如果代码的其他部分想查看线程是否被中断,它们应该执行以下操作
if (Thread.currentThread().isInterrupted()) {
// clean up and exit the thread...
break;
}
另一个解决方案是将观察线程设置为守护线程。这意味着当主线程完成时,JVM将立即退出,而不是等待watchThread
完成。它不如上面的中断那么好,因为它可以在代码中间停止“<代码>监视线程< /代码>”,做一些重要的文件IO。< /P>
Thread watchThread = new Thread(new WatchRunnable());
watchThread.setDaemon(true);
watchThread.start();
当用户指示主线程终止时,如何强制后台侦听线程退出
你应该中断线程。WatchService.take()
方法抛出InterruptedException
。这意味着当主线程完成时,它可以中断watch服务线程。这将导致take()
方法抛出一个InterruptedException
,使监视线程有机会清理并退出while
循环,然后从run()
方法返回
Thread watchThread = new Thread(new WatchRunnable());
watchThread.start();
// ...
// when the main thread wants the program to stop, it just interrupts the thread
watchThread.interrupt();
// although not necessary, main thread may wait for the watch-thread to finish
watchThread.join();
当您捕获到InterruptedException时,重新中断线程以使
@Override
public void interrupt() {
super.interrupt();
System.out.println("Interupt is called");
try {
watcher.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
try {
key = watcher.take();
} catch (InterruptedException x) {
System.out.println("take() is interrupted");
Thread.currentThread().interrupt();
return;
} catch (ClosedWatchServiceException e) {
System.out.println(" take is killed from closedException");
return;
}
public static void main(String[] args) throws InterruptedException {
WatchDir watchDir = new WatchDir(path);
Thread.currentThread().sleep(1000);
watchDir.shutDown();
watchDir.interrupt();
watchDir.join();
System.out.println("the WatchDir thread is killed");
}