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. :-)
Nguồn
2010-05-16 17:20:34
Đâ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
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
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. –