Следует ли использовать Thread.sleep при чтении из FIFO?

В связи с тем, что почти в каждом вопросе, касающемся использования Thread.sleep, в основном указывается на его использование только в определенных ситуациях, я пришел спросить вас, правильно ли использовать его в моем случае или есть ли лучший способ сделать это.

Операционная система - Linux(Debian), в которой запущен скрипт bash, который определяет, когда устройство (в частности, устройство хранения) вставляется / удаляется, а затем записывает в FIFO строку с типом "ADD {путь". -to-dev}"или"REM {path-to-dev}".

Я создал небольшое приложение в Java, которое использует два потока. Первый поток вызовет метод read, который анализирует String для стандартного вывода, после чего он будет ждать (). Второй поток проверит, является ли FIFO пустым или нет, и затем, когда он увидит, что строка была вставлена, он вызовет notify(), так что другой поток напечатает строку там и так далее. Внутри цикла, где он проверяет, есть ли у 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;

}}

В основном я просто создаю темы и запускаю их.

    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 Large, не было необходимости опрашивать на предмет готовности. Я не знал, что если нет строки, readLine() будет "спать", и нет необходимости опрашивать его. Я удалил поток уведомлений и просто сохранил ReadThread, который вызовет метод Detect readFromFifo(), и все это работает хорошо. @dumptruckman, спасибо за предложение. Хотя это не относится к моему делу, я не знал о WatchService, и это было хорошее чтение, хорошие вещи, которые нужно знать. @Nyamiou Galeanthrope, таймер был бы полезен, но, как я уже сказал, я оставляю только один поток для выполнения того же метода, и он работает как задумано.@Krzysztof Cichocki, спасибо за указание на наличие проблем. Я знал об этом, иначе я бы не задавал этот вопрос.

0 ответов

Другие вопросы по тегам