2010-05-16 23 views
7

Tôi cần có luồng đệm char được đệm, mà tôi viết trong một chuỗi và từ đó tôi đọc trong một chuỗi khác. Right now Tôi đang sử dụng PipedReaderPipedWriter cho nó, nhưng các lớp đó gây ra sự cố hiệu suất: PipedReader thực hiện wait(1000) khi bộ đệm trong của nó trống, khiến ứng dụng của tôi bị trễ rõ ràng.Thay thế tốt hơn cho PipedReader/PipedWriter?

Sẽ có một số thư viện thực hiện tương tự như PipedReader/PipedWriter, nhưng với hiệu suất tốt hơn? Hoặc tôi sẽ phải thực hiện bánh xe của riêng tôi?

+0

Đây có thể không phải là những gì bạn muốn, nhưng liệu chuỗi viết của bạn có thể thông báo cho chuỗi đọc sau khi đã viết gì đó không? Và chuỗi đọc sẽ tiếp tục đọc trong khi 'ready()' là đúng, sau đó ngủ khi nó không? – Phil

+0

Bạn có thể cho chúng tôi thấy mã của bạn không?'Wait (1000)' không phải là vấn đề, bởi vì người viết thông báo cho người đọc khi có thứ gì đó được viết. Người đọc sau đó thoát khỏi sự chờ đợi của mình(). – tangens

+0

Cảm ơn, Phil. Bây giờ tôi không ở nhà, vì vậy tôi không thể kiểm tra nó, nhưng dựa trên mã nguồn PipedWriter.flush() xuất hiện để thông báo cho người đọc. Tôi sẽ thử nó sau ngày hôm nay. –

Trả lời

5

Vấn đề là khi một cái gì đó được ghi vào PipedWriter, nó không tự động thông báo cho PipedReader rằng có một số dữ liệu cần đọc. Khi một người cố gắng đọc PipedReader và bộ đệm trống, PipedReader sẽ lặp lại và chờ sử dụng cuộc gọi wait(1000) cho đến khi bộ đệm có một số dữ liệu.

Giải pháp là gọi PipedWriter.flush() luôn sau khi viết gì đó cho đường ống. Tất cả những gì tuôn ra là gọi notifyAll() trên đầu đọc. Bản sửa lỗi cho mã được đề cập đến looks like this.

(Đối với tôi việc thực hiện PipedReader/PipedWriter trông rất giống với trường hợp tối ưu hóa sớm - tại sao không thông báo cho tất cả trên mỗi lần ghi? Cũng vậy, người đọc chờ đợi trong một vòng lặp hoạt động, thức dậy mỗi giây, thay vì chỉ thức dậy khi có là một cái gì đó để đọc. Mã cũng chứa một số ý kiến ​​todo, mà người đọc/nhà văn phát hiện thread mà nó không phải là đủ tinh vi.)

Vấn đề này cũng xuất hiện trong PipedOutputStream. Trong dự án hiện tại của tôi gọi flush() bằng tay là không thể (không thể sửa đổi số IOUtils.copy() của Commons IO), vì vậy tôi đã sửa nó bằng cách tạo low-latency wrappers cho các lớp ống. Họ làm việc tốt hơn nhiều so với các lớp học ban đầu. :-)

1

Sẽ khá dễ dàng để bao bọc API luồng char xung quanh BlockingQueue.

Tôi phải nói, tuy nhiên, có vẻ như ngược lại rằng PipedReader sẽ sử dụng bỏ phiếu để chờ dữ liệu. Đây có phải là tài liệu ở đâu đó không, hoặc bạn tự khám phá nó bằng cách nào đó?

+0

Tôi nghĩ bạn có ý định liên kết tới "http://java.sun.com/javase/6/docs/api/java/util/concurrent/BlockingQueue.html" – Phil

+0

Vâng, đó là kế hoạch của tôi B, nếu tôi không thể tìm một lớp học đã làm những gì tôi cần. –

+0

Cảm ơn Phil. Tôi đã quá nhanh trên bản vẽ với tìm kiếm Google của tôi. :-) –

0

Tôi đã triển khai một cái gì đó tương tự một chút và asked a question cho dù bất kỳ ai khác có bất kỳ suy nghĩ và mã thử nghiệm nào tốt hơn.

1

@Esko Luontola, tôi đã đọc qua mã của bạn trong gói sbt để cố gắng hiểu bạn đang làm gì. Có vẻ như bạn muốn bắt đầu một số Process và chuyển đầu vào cho nó và có kết quả của hành động được thực hiện ở những nơi khác nhau. Điều này có đúng không?

tôi sẽ cố gắng sửa đổi vòng lặp chính trong ReaderToWriterCopier để thay vì làm một read() - một hoạt động ngăn chặn điều đó rõ ràng khi một PipedReader được tham gia bỏ phiếu gây ra - bạn một cách rõ ràng chờ cho Writer-flush. Các tài liệu rõ ràng là flush gây ra bất kỳ Reader s để được thông báo.

Tôi không chắc chắn cách chạy mã của bạn để tôi không thể hiểu sâu hơn về nó. Hi vọng điêu nay co ich.

+0

Trường hợp sử dụng của tôi là có nhiều độc giả cho bản in 'Quy trình' và mỗi người đọc đó cần bản sao luồng riêng, bắt đầu từ thời điểm hiện tại và kết thúc khi người đọc đóng. Các độc giả khác nhau không ảnh hưởng lẫn nhau. Người đọc PipedReader là ví dụ 'OutputReader.waitForOutput()'. Người viết là 'ReaderToWriterCopier'. Chương trình chính là 'SbtRunner', và các nguồn kiểm tra có' SbtRunnerTester' sử dụng nó. SBT là viết tắt của http://code.google.com/p/simple-build-tool/ –

Các vấn đề liên quan