2012-05-02 4 views
4

데이터베이스에서 읽고 파일에 결과를 쓰는 직렬 프로그램을 수정하려고합니다. 블로킹 방식으로 메모리 버퍼가 있고 비동기 적으로 "백그라운드"로 쓰여지는 파일을 성능 향상을 얻을 수 있다고 생각합니다.유사점 및 차이점 Java에서 비동기 파일 작성을위한 PipedOutputStream/PipedInputStream (또는 Reader/Writer) 및 BlockingQueue

"인터뷰"솔루션은 스레드, 공유 리소스, 동기화 된 블록 등 ... 하지만 더 좋은 방법이 있다고 확신합니다 (거기에 멋진 "지연된 쓰기"라이브러리가 있습니다. 나를 위해 그것을 수행 할 것입니까?)

java.util.concurrent 패키지는 어떤 도움을 제공합니까? java.nio? 또는 아마 JMS/ActiveMQ?

내 버퍼에 대한 기초로 PipedOutputStream/PipedInputStream은 어떨까요?

지연/백그라운드/버퍼링/비 차단/비동기 파일 작성기를 Java로 구현하려면 어떻게해야합니까?

편집 :

제안을 바탕으로, 여기에 더 집중하게하려는 시도이다 (나는이 답변의 의견과 투표에 따라 여전히 관련이 생각하는)이 질문은 폐쇄 것을 방지 할 수 있습니다. 사이의 실제적인 차이가 무엇

  • (나는 아주 좋은 사람이 있기 때문에 답변이 여전히 문맥에 남아 있도록 위의 원래의 질문을 유지하고있어) PipedOutputStream/PipedInputStream (또는 PipedReader/PipedWriter) 및 BlockingQueue
  • 비동기 파일 쓰기에 후자를 사용하는 것이 바람직합니까? (또는 내가 이유를 알고 싶습니다, 오렌지 비교에 만일 그렇다면이 사과입니까?) 당신은 아마합니다 (생산자 (데이터베이스 리더)와 소비자 사이의 경계 블록 큐를 사용하려면
+1

귀하의 게시물은 토론 주제가 아닌 주제에 관한 주제가 아닙니다. 몇 가지 제안을 시도한 다음 구체적인 질문을 게시하십시오. –

+2

나는 토론에 관심이있다. 나는이 주제에 대해 주제를 벗어났다는 것을 존경하지만, 주제에 관한 질문을 다시하는 것을 용서해 준다. 특정 프로그래밍 문제에 대해 그렇게 할 필요가없는 많은 사람들이 있다고 확신합니다. (누군가 99 % 전에 그것을 물어 본) 코드를 알아낼 것입니다. 그러나 "그것을 수행하는 방법이 백만 가지가 아닙니다. 무엇이 가장 좋은 연습 방법 "입니다, 이것은 내가 바라는 진짜 동료 의견입니다. http://programmers.stackexchange.com의 약자입니다. 내 질문을 저기로 옮겨야 하나? 나는 바로 일을하고 싶고, 올바른 일을하고 싶다. –

+2

글쎄,이 질문은 친절하다. – keuleJ

답변

5

파일 작성자).

Java의 ArrayBlockingQueue이 작업을 매우 훌륭하게 처리합니다. 생산자는 버퍼가 가득 차면 차단하여 너무 많은 메모리를 소비하는 문제를 피합니다.

동시 스레드에서 생성하고 소비하는 작업은 Java 프레임 워크 Executors을 사용하는 것이 가장 좋습니다.

+0

이것은 내가 찾던 답변의 일종으로 BlockingQueue와 Executors를 모두 시도해 볼 것이다. 저는 실제로이 답변에 사용 된 Writer 스 니펫을 사용하려고합니다. http://stackoverflow.com/a/3604974/239168. 그런데 BlockingQueue가 아닌 BlockingDeque가 사용 된 이유가 있습니까? –

+0

링크를 보지 않았지만 표준 프로듀서 소비자 시나리오에서 큐를 통해 대기열에서 큐를 제거 할 필요가 없어야합니다. –

2

스레드, 공유 리소스, 동기화 된 블록 등을 사용하여 "취업 면담"해결책을 생각할 수 있지만 더 좋은 방법이 있다고 확신합니다. 좋은 "지연된 쓰기"라이브러리가 있습니까? 거기서 저를 위해 그것을 할 것입니까?)

나는 "지연된 쓰기"라이브러리를 발견하지 못했습니다. 하지만 이것은 큐/버퍼에서 읽고 블로킹 출력에 쓰는 전용 스레드를 사용하여 큐 또는 순환 버퍼에 쓰는 출력 스트림/기록기라고 생각합니다. 이 작업은 가능하지만 이중 데이터 복사 비용을 복사하지 않는 것이 좋습니다.

java.util.concurrent 패키지 중 어떤 것이 도움이됩니까?

가능합니다.

java.nio?

가능합니다.

또는 아마도 JMS/ActiveMQ?

로컬 파일에 쓰는 것이 목표라면 의심 스럽습니다.

내 버퍼의 기초로 PipedOutputStream/PipedInputStream은 어떻습니까?

그게 도움이 될 수 있습니다. 그러나 여전히 스트림을 읽고 쓰는 스레드를 구현해야합니다. 당신이 이것을 구현하는 방법의 메커니즘을 무시


, 나는 당신이 경우 비동기 I/O를 수행하여 상당한 속도 향상을 얻을 것이라고 생각한다. 응용 프로그램을 현재 양식으로 프로파일 링하는 경우 기본 병목 현상이 데이터베이스에서 데이터를 가져 오는 것입니다. 파일에 쓰기가 훨씬 빠르게 진행됩니다. 그렇다면 중복되는 데이터베이스 및 파일 I/O로 인해 상당한 속도 향상을 기대하기는 어렵습니다.

파일 출력이 병목 현상이되는 경우 출력 스트림 버퍼 크기를 늘리는 것이 더 간단합니다. 이 작업은 간단합니다. 추가 버퍼 크기 매개 변수를 BufferedOutputStream 생성자에 추가하기 만하면됩니다. 주요 재 작성을 시작하기 전에 시도해야합니다.

+0

이것은 매우 유용한 답변입니다. 코드의 가장 좋은 부분은 작성할 필요가 없다고 생각하는 코드입니다. 나는 초기에 파일 IO가 병목 현상이 아니라고하더라도, 내가 그것을 기다리지 않으면 적어도 약간의 개선이있을 것이라고 생각하지만, 나는 먼저 프로파일 링해야한다는 데 동의한다.나는 실제로 파일 입출력이 엄청나게 빠르다고 생각한다. 이것은 그 자체만으로도 매우 좋은 대답이 될 것이라고 생각하지만, BufferedOutputStream에 대한 여러분의 의견은 또 다른 "명백하게, 그러나 내가 어떻게 생각하지 않았는가"라는 순간은 귀중하다. –

+1

다른 방법들에 대해 토론하기 속도를 높이려면 대량의 데이터를 읽는 경우 SQL ResultSet의 반입 크기를 늘려야합니다. 이는 DB 통신의 혼란을 피함으로써 엄청난 속도 향상을 가져올 수 있습니다. –

+0

감사합니다. stmt.setFetchSize (n)을 사용 하시겠습니까? –

1

Java 7에는 'NIO 2'의 비동기 I/O가 있습니다.

Java 7을 사용할 수 없다면 솔직히 구현하려고하지 않아도됩니다. 선물과 관련하여 무서운 것을 할 수는 있지만, 얻은 이익은 부정적이지 않으면 0이 될 것입니다.

+0

이것은 좋은 지적이며, 찾아 볼 것입니다. –