从FIFO读取时是否应该使用Thread.sleep?

时间:2017-05-18 12:47:02

标签: java multithreading file file-read

由于几乎所有关于使用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,感谢指出存在问题。我知道这一点,否则我不会问这个问题。

0 个答案:

没有答案