2014-07-01 4 views
2

모두 BufferReader 파일 읽기 모두, 스레드에서 해당 파일을 읽으려면 BufferedReader을 사용하려고하는 파일을 여러 스레드에서 쓰려고합니다.여러 스레드가 파일에 쓸 때

코드는 다음과 같습니다.

FileReader reader = new FileReader(file); 
BufferedReader br = new BufferedReader(reader); 
String detail; 
while ((detail =br.readLine()) != null) 
{ 
    ... 
} 

현재 잘 작동하는 것 같습니다. 하지만 그것에 대해 몇 가지 질문이 있습니다. 질문이 어리석은 경우. 제발 웃지 마세요. 감사.

루프가 깨진 적이 없습니까? 다른 스레드가 파일에 쓰고 있기 때문입니다. 어쩌면 readLine()이 null을 반환하지 않을 수도 있습니다.

업데이트

의 3 개 스레드 (T1, T2, T3)이있는 가정 해 봅시다.

T1 및 T2는 기록기입니다.

T3는 독자입니다.

코드는 아래의 순서로 실행됩니다.

1. 현재 파일 행 번호 100

2.T1 파일 저장 라인을 작성한다. (파일 라인 (101)에 증가)

3.T3는 (101)에 파일의 마지막 행을 판독 . 다음의 read는 null를 리턴합니다.

4.T2

는 파일에 한 줄을 추가합니다. (파일 라인이 102 증가)

5.T3 다시 읽어 ... (T2 그냥 파일에 새 줄을 추가했기 때문에? 널 여부를 반환 않는다 T3 읽기 전에 다시 읽으십시오.)

미리 검토해보십시오. 감사합니다.

+1

독자가 작성자보다 더 빨리 읽는 경우 결국 파일 끝에 도착한 다음 null을 반환합니다. 그렇지 않다면 파일 시스템에 여유 공간이 부족하고 작성자가 IOException으로 멈출 때 완료됩니다. –

+0

@Pablo 내가 말한 경우가 발생할 수 있는지 확실하지 않습니다. 경주 문제처럼 들리니? 덕분에 –

+0

시나리오를 시뮬레이션하려면 스레드 우선 순위 또는 절전 시간을 설정할 수 있습니다 – yushulx

답변

3

네, 루프가 끝나지 않을 수도 있습니다 (적어도 메모리가 부족할 때까지). 여기를 증명할 수있는 코드는 다음과 같습니다

public class test { 

    public static void main(String[] args) { 
// start thread to write to file 
     new Thread(new Runnable() { 
      @Override 
      public void run() { 
       FileWriter writer; 
       try { 
        int i = 1; 
        writer = new FileWriter("D:\\text.txt"); 
        writer.append("line"+ i++ + "\n"); 
        writer.flush(); 
        while (true) 
        { 
         writer.append("line"+ i++ + "\n"); 
         writer.flush(); 
        } 
       } catch (IOException e) { 
        e.printStackTrace(); 
       } 

      } 
     }).start(); 

     try { 
      Thread.sleep(500); 
     } catch (InterruptedException e1) { 
      // TODO Auto-generated catch block 
      e1.printStackTrace(); 
     } 

     // start thread to read file 
     new Thread(new Runnable() { 
      @Override 
      public void run() { 
       try { 
        FileReader reader = new FileReader("D:\\text.txt"); 
        BufferedReader br = new BufferedReader(reader); 
        String detail; 
        while ((detail =br.readLine()) != null) 
        { 
         System.out.println(detail); 
        } 
        br.close(); 
       } catch (IOException e) { 
        e.printStackTrace(); 
       } 

      } 
     }).start(); 

    } 
} 
+0

맞습니다. 나는 또한 당신 같은 시험을했습니다. 그것은 일어날 수 있었다. 끝내지 마라. –

-1

당신은 절대적으로 맞습니다. 파일에 내용을 쓰는 쓰레드를 계속 작성하는 경우에도 교착 상태가 발생할 수 있습니다. 쓰레드가 파일 쓰기를 계속한다면 루프에서 빠져 나올 가능성이 없습니다. 무한 상태로

+1

그러나 디스크 공간이 무한하지 않고 작성자가 영원히 쓸 수 없습니다 –

+1

무한 루프가 교착 상태가 아닙니다. – EJP

+0

예. 당신은 맞습니다.하지만 요청 시간 초과 시나리오에 영향을 미칠 수 있다고 믿습니다. @Pablo – Nadendla

0

내가 그것을위한 몇 가지 실험을했다.

한 일식은 작성자로 프로그램을 실행합니다.

다른 이클립스는 프로그램을 독자로 실행합니다.

public class Main { 

    /** 
    * @param args 
    * @throws IOException 
    */ 
    public static void main(String[] args) throws IOException { 
     // TODO Auto-generated method stub 

     StringBuffer intiLine = new StringBuffer(""); 
     FileReader reader = new FileReader("D:\\logs\\notify-subscription.log"); 
     BufferedReader br = new BufferedReader(reader); 
     String detail; 
     while ((detail =br.readLine()) != null)//debug and set breakpoint here 
     { 
      System.out.println(detail); 
     } 
    } 
} 

내가 테스트를 시작하기 전에. 원본 로그 파일의 내용이 비어 있습니다. 처음 독자 프로그램을 실행했습니다. br.readLine()의 결과는 null입니다. 하지만 실행하기 전에 코드 라인 while ((detail =br.readLine()) != null)에서 중단 점을 설정하고 작성자 프로그램을 실행했습니다. 따라서 파일에 test test test이 포함되어 있습니다. br.readLine()은 null이 아니게됩니다.

관련 문제