2013-11-15 35 views
-1

我正在開發一些必須讀取日誌文件的程序,我認爲我在其中構建了一個智能機制,結果代碼甚至沒有編譯...Thread.sleep的中斷處理調用Thread.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.sleepInterrruptedException再次處理。

我認爲它需要轉換到一些while循環,但究竟我該如何做到這一點?

編輯:對不起,我忘了把這個想法背後的這個計劃。但是我想要實時監控一個日誌文件,所以它永遠不會停止讀取文件,除非我在關閉消息中指出這種情況。

+0

嘗試拋出整個'if(line == null)'部分。 'reader.readLine()'應該阻塞,直到有東西要讀。 – zapl

+2

@zapl沒有達到文件結尾。 –

+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

對不起,我忘了把它放在我的文章中。但是這個想法是它會監視一個日誌文件,所以我不想在EOF達到時退出。 – skiwi

+0

我爲此添加了一個部分。然而,你需要擔心獨佔文件鎖定。 – TwoThe

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); 
      } 
     } 
-1

你可以不喜歡的答案,但嘗試寫Java程序的使用外殼istead。我自己是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(); 
    } 
} 
+0

如果你打算建議比Java更有意思的東西,那麼請將其添加到答案中,當你指出自己已經使用它時更是如此。不幸的是,這最終會在Windows Server上運行。如果發生第二個InterruptedException,您的Java建議也不能正確覆蓋該案例。 – skiwi

+0

我很抱歉讓你用自己的代碼讓你失望;)。 – goroncy