2013-09-24 3 views
1

Java에서 파일을 읽는 스레드를 만들고 있습니다. 2 개의 쓰레드를 만들 때 각 쓰레드는 파일의 다른 부분을 읽는 동안 전체 파일을 읽습니다. 나는 sleep(), join(), yield()를 넣으려고했으나 그들을 포함시킨 후에는 읽기를 느리게하고있다. 나는 잠을 호출 (라인으로 라인을 읽기) while 루프에서 ReadFile을에서 Java에서 파일을 읽는 멀티 스레딩

public class MyClass implements Runnable { 

    Thread thread; 
    public MyClass(int numOfThreads) { 
     for(int i=0;i < numOfThreads; i++) { 
      thread = new Thread(this); 
      thread.start(); 
     } 
    } 

    public void run() { 
     readFile(); 
    } 
} 

,()/수율(). 스레드가 파일의 다른 부분을 읽게하려면 어떻게해야합니까?

파일을 읽는 데 사용 방법 업데이트 ...

public synchronized void readFile() { 
    try { 
     String str; 
     BufferedReader buf = new BufferedReader(new FileReader("read.txt"); 
     while ((line = buf.readLine()) != null) { 
      String[] info = str.split(" "); 
      String first name = info[0]; 
      String second name = info[1]; 
      try { 
       Thread.sleep(100); 
      } catch (InterruptedException e) { 
      } 
     } catch (IOException e) { 
     System.out.println("Error : File not found"); 
     e.printStackTrace(); 
    } 
} 
+0

어디 파일을 읽고 코드? – MadProgrammer

+0

public synchronized void readFile() { 시도 { 문자열 str; BufferedReader buf = new BufferedReader (새 FileReader ("read.txt"); \t while ((line = buf.readLine()) while!= null) \t { \t String [] info = str.split (""); \t 문자열 이름 = 정보 [0]; \t 문자열 second name = 정보 [1]; \t 시도 { \t \t \t \t \t \t \t에 Thread.sleep (100); \t} \t \t \t \t 캐치 (예외 : InterruptedException 전자) \t \t \t \t { \t \t \t \t} \t \t \t} \t \t 캐치 (IOException이 전자) { \t \t \t \t에서 System.out.println ("오류 : 파일을 찾을 수 없습니다"); \t \t \t \t e.printStackTrace(); \t \t \t }} 다음을 사용할 수 – user1690394

+4

[RandomAccessFile의 (http://docs.oracle.com/javase/7/docs/api/java/io/RandomAccessFile.html) 파일 내의 임의의 위치에서 읽어야 그러나 "선들"을 이해하지는 못합니다. 줄을 찾으려면 줄 바꿈은 데이터의 어느 곳에서나있을 수 있으므로 전체 파일을 스캔해야합니다. 그것이 구조화 된 데이터가 아니라면. –

답변

16

나는이 같은 여러 스레드로 파일을 읽는 것은 하나 읽기보다 더 빨리 될 것이라고 생각하는 가정합니다. 이것은 거의 틀린 거짓입니다. 스레드는 여러 코어 나 프로세서를 사용하여 CPU 바운드 작업에서 더 나은 성능을 얻습니다. 그러나 파일 읽기는 CPU와 관련된 작업이 아닙니다.

OS는 디스크 컨트롤러를 사용하여 디스크 인터페이스의 전체 대역폭에서 바이트를 읽습니다. 거의 모든 하드웨어 조합에서 속도는 디스크 (읽기 및/또는 검색 시간), 컨트롤러 및 CPU가 아닌 DMA 인터페이스 또는 버스로 제한됩니다. CPU가 디스크 컨트롤러를 100 % 사용 중으로 유지하는 것은 쉽습니다. 이 사실을 증명해야하는 경우 큰 파일 복사본을 시작하고 CPU 사용률을 살펴보십시오. 그것은 그렇게 높지 않을 것입니다.

따라서 여러 스레드 중에서 한 번에 하나만 실행되므로 단일 스레드 계산에 오버 헤드가 추가됩니다.

무엇이 입니까? 느린 파일 전송이 버퍼링 중입니다. 유연성을 확보하기 위해, I/O 라이브러리는 각 문자를 2 또는 3 번 버퍼링 할 수 있습니다.

Java NIO 라이브러리는 가능한 한 많은 오버 헤드를 없애기위한 것입니다. 예를 들어 this article을 참조하십시오. 비슷한 것들이 많이 있습니다. 내 경험에 따르면 신중하게 작성된 NIO 리더는 하드웨어의 성능을 대부분 사용하게됩니다.

주의 사항 : 바이러스 검사 프로그램을 사용하여 읽는 파일 종류를 검사하도록 설정 한 경우 CPU가 바운드 될 수 있습니다. 이례적인 경우에는 검사기 아키텍처에 따라 멀티 스레딩을 사용하는 것이 좋습니다. 이 경우 전체 파일 크기 S를 알 수 있고 스레드 k = 0,1, .., n-1을 오프셋 kS/n에서 (k + 1) S/n - 1로 읽습니다 (seek에 의해 각 스레드에서 읽은 바이트 수를 오른쪽 오프셋 및 추적). 그러나 나는 여전히 추가 헤드 검색 시간과 무작위 액세스의 다른 효과가 여러 스레드에서 바이러스 검사기를 실행하는 이점을 취소한다는 것을 강하게 의심합니다.

-1

프로그램에서 string.split ("")은 실행 속도가 느려질 수 있습니다. 자신의 글을 쓰면 속도가 6 배 향상됩니다. 이 같은 뭔가 도움이 될 것입니다

int index = vcf_record_string.indexOf("\t"); 
vcf_record_string.substring(0, index) 

은 시스템의 I/O, 여기 당신이 어떻게 할 수있다 높은 처리량을 지원하는 경우 How to read a file using multiple threads in Java when a high throughput(3GB/s) file system is available