Thread.sleep的中断处理调用Thread.sleep

时间:2013-11-15 11:26:17

标签: java multithreading sleep

我正在开发一些必须读取日志文件的程序,我认为我在其中构建了一个智能机制,结果代码甚至没有编译......

我犯了一个很大的设计缺陷:如何修复它?

public class Reader implements Runnable {
    private volatile boolean isReading;

    private final File file;

    public Reader(final File file) {
        this.file = file;
    }

    @Override
    public void run() {
        BufferedReader reader = null;
        try {
            reader = new BufferedReader(new FileReader(file));
        } catch (FileNotFoundException ex) {
            throw new IllegalStateException("bf4logreader.Reader.run: File has not been found. file = " + file);
        }
        while (isReading) {
            String line = null;
            try {
                line = reader.readLine();
            } catch (IOException ex) {
                throw new IllegalStateException("bf4logreader.Reader.run: Something went wrong when reading file. file = " + file);
            }
            if (line == null) {
                //No new lines
                long startSleepTime = System.currentTimeMillis();
                try {
                    Thread.sleep(SLEEP_TIME);
                } catch (InterruptedException ex) {
                    if (isReading) {
                        //Not supposed to be interrupted
                        Thread.sleep(System.currentTimeMillis() - startSleepTime);
                    }
                    else {
                        try {
                            //Needs to shutdown
                            reader.close();
                        } catch (IOException ex1) {
                            Logger.getLogger(Reader.class.getName()).log(Level.SEVERE, null, ex1);
                        }
                    }
                }
            }
            else {
                //Process new lines
                System.out.println("Line: " + line);
            }
        }
    }

    public void shutdown() {
        isReading = false;
    }
}

我觉得自己很聪明,让线程在睡觉的时候仍然不得不睡觉,如果它被不适当地打断了。但是我当然不能在这个阵营中这样做,因为它需要再次处理Thread.sleep的{​​{1}}。

我认为它需要转换到某个InterrruptedException循环,但具体如何呢?

编辑:对不起,我忘了把这个想法放在这个程序背后。但是我希望监视一个日志文件,所以它永远不会停止读取文件,除非我用关闭消息指示这个。

3 个答案:

答案 0 :(得分:1)

请尝试使用以下代码:

try (BufferedReader reader = new BufferedReader(new FileReader(file))) {
  String line;
  while (running) {
    while ((line = reader.readLine()) != null) {
      System.out.println(line);
    }
    Thread.sleep(1000); // end of file has been reached, wait a second for more data
  }
} catch (FileNotFoundException ex) {
  // ...
} catch (IOException ex) {
  // ...
} catch (InterruptedException ex) {
}

try (ressource) catch成语将确保读者在任何情况下都能正常关闭,因此您不必担心这一点。

readLine()函数将自动阻止(保持当前执行)直到数据可用,因此不需要任何睡眠或类似操作。如果它返回null,则到达文件的末尾,因此您可以退出。

如果抛出任何InterruptedException,则线程将正确终止。这个异常总是被抛出作为线程的信号,以便尽快退出工作,所以你永远不应该忽略它。

通过抛出完全不同的异常来处理像IOException这样的常见异常通常是错误的,因为它隐藏了错误的实际原因。而只是处理首先抛出的错误。
另外一个IllegalStateException是一个RuntimeException,它通常不会被捕获,导致整个代码立即终止。你可能不想要那个。

答案 1 :(得分:0)

检查这是否有帮助

 RandomAccessFile in = new RandomAccessFile("/home/hduser/Documents/Sample.txt", "r");
        String line;
        long length = 0;//used to check the file length
        while (true) {
            if(in.length()<length){//new condition to reset position if file length is reduced 
                in.seek(0);
            }
            if ((line = in.readLine()) != null) {
                System.out.println(line);
                length = in.length();
            } else {
                Thread.sleep(2000);
            }
        }

答案 2 :(得分:-1)

您可能不喜欢这个答案,但尝试使用shell而不是编写Java程序。我自己是Java开发人员,但如果我听说有与日志有关的事情,我尝试使用unix / linux shell。编写Java代码会花费你20倍的时间,你可能找不到所有边缘情况而且很难改变任何东西,因为你的程序将是200行代码而不是5行。

你的代码。它远非完美,尽管你的担心是没有编译。在这里,你的班级先生将会编译甚至工作。排序:

import java.io.*;
import java.util.logging.Level;
import java.util.logging.Logger;

public class Reader implements Runnable {
  private volatile boolean isReading;

  private final File file;

  public Reader(final File file) {
    this.file = file;
  }

  @Override
  public void run() {
    BufferedReader reader;
    try {
      reader = new BufferedReader(new FileReader(file));
    } catch (FileNotFoundException ex) {
      throw new IllegalStateException("bf4logreader.Reader.run: File has not been found. file = " + file);
    }
    isReading = true;
    while (isReading) {
      String line;
      try {
        line = reader.readLine();
      } catch (IOException ex) {
        throw new IllegalStateException("bf4logreader.Reader.run: Something went wrong when reading file. file = " + file);
      }
      if (line == null) {
        //No new lines
        long startSleepTime = System.currentTimeMillis();
        try {
          Thread.sleep(500);
        } catch (InterruptedException ex) {
          if (isReading) {
            //Not supposed to be interrupted
            try {
              Thread.sleep(System.currentTimeMillis() - startSleepTime);
            } catch (InterruptedException e) {
              e.printStackTrace();
            }
          }
          else {
            try {
              //Needs to shutdown
              reader.close();
            } catch (IOException ex1) {
              Logger.getLogger(Reader.class.getName()).log(Level.SEVERE, null, ex1);
            }
          }
        }
      }
      else {
        //Process new lines
        System.out.println("Line: " + line);
      }
    }
  }

  public void shutdown() {
    isReading = false;
  }


  public static void main(String[] args) throws InterruptedException {

    Reader reader = new Reader(new File("res/integers.txt"));
    new Thread(reader).start();
    Thread.sleep(1000);
    reader.shutdown();
  }
}