由于几乎所有关于使用Thread.sleep的问题,它主要表示仅在某些情况下使用它,我来问你在我的情况下使用它是否正确或是否有更好的方法。
操作系统是Linux(Debian),其中运行bash脚本,检测何时插入/删除设备(更具体地说,存储设备),然后将类型&下的字符串写入FIFO #34;添加{path-to-dev}"或" REM {path-to-dev}"。
我在java中创建了一个小应用程序,它使用了两个线程。第一个线程将调用一个read方法,该方法将String解析为标准输出,之后它将wait()。第二个线程将检查FIFO是否为空,然后,当它看到已插入一个String时,它将调用notify(),因此另一个线程将在那里打印String,依此类推。在它检查FIFO是否有数据的循环内部,我调用Thread.sleep(1000),我不确定这是否是一个好的方法。我将介绍处理所有操作的代码。
首先,具有阅读方法的类:
public class Detect {
private File file;
private BufferedReader read;
private volatile boolean readable;
private static String readFromFile;
public Detect() throws FileNotFoundException {
file = new File("/hardware_stuff/hardware_events");
read = new BufferedReader(new FileReader(file));
readable = true;
}
synchronized String readFromFifo() {
while (!readable) {
try {
wait();
} catch (InterruptedException ex) {
System.out.println("Interrupted during the wait for read.");
}
}
try {
while (read.ready()) {
readFromFile = read.readLine();
}
} catch (IOException ex) {
System.out.println("Error in reading from FIFO.");
}
readable = false;
notify();
return readFromFile;
}
synchronized void waitForFifo() {
while (readable) {
try {
wait();
} catch (InterruptedException ex) {
Logger.getLogger(Detect.class.getName()).log(Level.SEVERE, null, ex);
}
}
try {
while (!read.ready()) {
Thread.sleep(1000);
System.out.println("Sleeping due to lack of activity in FIFO in thread : " + Thread.currentThread().getName());
}
} catch (IOException | InterruptedException ex) {
Logger.getLogger(Detect.class.getName()).log(Level.SEVERE, null, ex);
}
readable = true;
notify();
}}
接下来,将从中读取的线程。
public class ReadThread extends Thread {
Detect detect;
private boolean shouldBeRunning;
public ReadThread(Detect detect) {
this.detect = detect;
shouldBeRunning = true;
}
@Override
public void run() {
while (shouldBeRunning) {
String added = detect.readFromFifo();
System.out.println(added);
}
}
public void stopRunning() {
shouldBeRunning = false;
}}
最后,将检查FIFO是否为空的线程。
public class NotifyThread extends Thread {
Detect detect;
private boolean shouldBeRunning;
public NotifyThread(Detect detect) {
this.detect = detect;
shouldBeRunning = true;
}
@Override
public void run() {
while (shouldBeRunning) {
detect.waitForFifo();
}
}
public void stopRunning() {
shouldBeRunning = false;
}}
在main中我只是创建线程并启动它们。
Detect detect = new Detect();
NotifyThread nThread = new NotifyThread(detect);
ReadThread rThread = new ReadThread(detect);
nThread.start();
System.out.println("Started the notifier thread in : " + Thread.currentThread().getName());
rThread.start();
System.out.println("Started the reading thread in : " + Thread.currentThread().getName());
除了呼叫睡眠或其他方法,我可以用其他方法替换睡眠吗?我已经阅读了与此主题相关的其他问题,我仍然不确定/不知道这种情况是否适合睡眠。
更新:正如@james大说的那样,没有必要进行民意调查。我不知道如果没有行,readLine()将会“睡觉”。并且毕竟没有必要进行轮询。我删除了通知程序线程,我只是保留了ReadThread,它将调用Detect readFromFifo()方法并且一切正常。 @dumptruckman,谢谢你的建议。虽然它不适用于我的情况,但我并不知道WatchService,这是一个很好的阅读,很好的东西要知道。 @Nyamiou Galeanthrope,计时器本来有用,但正如我已经说过的,我只保留一个线程来执行相同的方法,它按预期工作。@ Krzysztof Cichocki,感谢指出存在问题。我知道这一点,否则我不会问这个问题。