我有这段代码。
// On a thread
try {
WatchService watcher = FileSystems.getDefault().newWatchService();
Path directory = Paths.get("properties");
WatchKey watchKey = directory.register(watcher, StandardWatchEventKinds.ENTRY_MODIFY);
while (true) {
for (WatchEvent<?> event : watchKey.pollEvents()) {
Path changed = (Path) event.context();
if (changed.toString().equals("radar.properties")) {
System.out.println("read call:");
readProperties();
}
}
if (!watchKey.reset()) {
break;
}
}
} catch (IOException e) {
FCSLogger.LOGGER.log(Level.SEVERE, "Exception while setting up WatchService", e);
}
// Method called by the above code
private void readProperties() {
try {
InputStream input = new FileInputStream(Paths.get("properties", "radar.properties").toString());
Properties prop = new Properties();
prop.load(input);
updateRate = Integer.parseInt(prop.getProperty("updateRate"));
System.out.println(updateRate);
input.close();
} catch (IOException e) {
e.printStackTrace();
}
}
它在第一次调用时返回正确的结果,然后阻塞整个线程。我隔离了此方法中的错误,因为在没有调用此方法的情况下,其他所有东西都可以正常工作。我想知道我在做什么错。 控制台输出快照:
// First change of file:
read call:
10
read call:
10
// Second change of file:
read call:
// I keep changing but nothing happens:
答案 0 :(得分:1)
可能是readProperties
抛出了NumberFormatException
,这导致您的观察者线程退出。
您可以包装对readProperties
的调用并捕获异常;这样至少在异常情况下观察者会继续观察。
并且您应该使用take
,以便监视程序线程阻塞。您当前的解决方案导致100%的CPU使用率。
请参阅下面的修改后的代码。我添加了一个写程序线程来更新文件,并且(毫无疑问?)readProperties
可能会失败,因为我们正在写文件时正在访问文件。可能的输出是:
....
property=5000
property=null
java.lang.NumberFormatException: null
at java.base/java.lang.Integer.parseInt(Integer.java:614)
at java.base/java.lang.Integer.parseInt(Integer.java:770)
at cl.ClientPoll.readProperties(ClientPoll.java:26)
at cl.ClientPoll.run(ClientPoll.java:46)
property=6000
property=7000
....
因此,观看时,您可以:跳过错误并继续;或使用其他API,以便在写入时锁定正在写入的文件。
示例代码
package cl;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.FileSystems;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardWatchEventKinds;
import java.nio.file.WatchEvent;
import java.nio.file.WatchKey;
import java.nio.file.WatchService;
import java.util.Properties;
public class ClientPoll extends Thread {
private void readProperties() {
try {
Path path = Paths.get("radar.properties");
InputStream input =new FileInputStream(path.toString());
Properties prop = new Properties();
prop.load(input);
String property = prop.getProperty("updateRate");
System.out.println("property="+property);
int updateRate = Integer.parseInt(property);
// System.out.println(updateRate);
input.close();
} catch (IOException e) {
e.printStackTrace(System.out);
}
}
@Override
public void run() {
try {
WatchService watcher = FileSystems.getDefault().newWatchService();
Path directory = Paths.get(".");
WatchKey watchKey = directory.register(watcher, StandardWatchEventKinds.ENTRY_MODIFY);
while (true) {
WatchKey wk = watcher.take();
for (WatchEvent<?> event : wk.pollEvents()) {
Path changed = (Path) event.context();
if (changed.toString().equals("radar.properties")) {
try {
readProperties();
} catch (Exception e) {
e.printStackTrace(System.out);
}
}
}
if (!watchKey.reset()) {
break;
}
}
} catch (IOException e) {
e.printStackTrace(System.out);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
new ClientPoll().start();
new Writer().start();
}
}
class Writer extends Thread {
@Override
public void run() {
try {
for (int i=0;i<10;i++) {
File f = new File("radar.properties");
FileWriter fw = new FileWriter(f);
fw.write("updateRate="+i*1000);
fw.close();
sleep(1000L);
}
} catch (Exception e) {
e.printStackTrace(System.out);
}
System.out.println("exit");
System.exit(0);
}
}