2012-05-14 42 views
7

Tôi có nhiều chủ đề đồng thời đọc cùng một tệp (hoàn toàn khoảng 100M) và chỉ có một luồng để cập nhật tệp. Tôi muốn ánh xạ tập tin trong bộ nhớ để giảm FILE I/O. Làm thế nào điều này có thể được thực hiện trong Java?Làm thế nào để thực hiện đọc đồng thời một tệp được ánh xạ tới bộ nhớ trong Java?

tôi về cơ bản đã xem xét 2 phương pháp sau đây:

  1. với mảng byte để lưu trữ các tập tin, và mỗi lần tạo ByteArrayInputStream để đọc bộ đệm khi multi-thread đọc.
  2. với NIO để nhận một kênh tệp, đồng bộ hóa kênh để đọc từ MappedByteBuffer để đọc nhiều luồng.

Tôi không chắc liệu các phương pháp có hoạt động hay không. Xin vui lòng giúp đỡ để cung cấp cho một số gợi ý nếu có một giải pháp tốt hơn.

+0

Nếu mọi người đọc và không ai đang viết, bạn không cần đồng bộ hóa chút nào. – EJP

+0

@EJP sẽ có một chủ đề để viết, tất cả các chủ đề khác đọc, tôi thích sử dụng ReadWriteLock trên byte [] để làm ngay bây giờ. –

+0

Cảm ơn, nhưng, với sự tôn trọng, câu hỏi của bạn không đề cập đến các nhà văn. Nó thay đổi hoàn toàn hình ảnh. Tôi đề nghị bạn chỉnh sửa sự kiện quan trọng đó vào câu hỏi của bạn. – EJP

Trả lời

12

Sử dụng NIO với mỗi chuỗi tạo bản đồ của riêng nó và đọc dữ liệu trong bộ đệm riêng tư của riêng nó. Giữ kích thước bộ đệm riêng tối ưu. Hệ điều hành đọc tệp trong bộ nhớ cache của tệp trong các trang và các trang được đọc vào bộ đệm riêng tư. Nếu cùng một vùng được đọc bởi nhiều luồng thì dữ liệu sẽ được đọc từ cùng một trang trong bộ đệm tệp lưu một số chu kỳ i/o của tệp. Dưới đây là một sơ đồ nhỏ để chỉ ra điều này. Hy vọng nó giúp hiểu rõ hơn.

memory mapped file io

Với tham khảo biểu đồ ở trên, dưới đây là một số giải thích. Vùng của tệp được ánh xạ tới bộ nhớ. Tạo một ánh xạ chỉ là một dấu hợp lý để nói rằng bạn muốn đọc từ một phần cụ thể của một tệp. Khi ánh xạ được tạo, vùng được ánh xạ sẵn sàng để đọc. Khi bạn bắt đầu đọc, hệ điều hành sẽ tải dữ liệu tệp vào các trang của nó trong bộ đệm tệp. Vùng có thể được ánh xạ tới một hoặc nhiều trang. Bây giờ, bạn đọc các trang vào bộ đệm riêng của bạn (nhiều trang tại một thời điểm để tối ưu hóa). Một số chủ đề khác có thể được đọc cùng một khu vực như là một trong những đầu tiên, do đó, nó cũng đọc cùng một trang vào bộ đệm riêng của nó. Lưu ý rằng lần đọc này xảy ra từ bộ đệm tệp mà không có lỗi trang. Sau khi bạn đã xử lý bộ đệm riêng của mình, bạn yêu cầu đọc thêm. Lưu ý rằng bạn đang đọc một phần bản đồ của bạn vào bộ đệm riêng của bạn tại một thời điểm. Tệp của bạn có thể là 100MB và bạn ánh xạ một phần 10MB vào bộ nhớ; và bạn coud có bộ đệm riêng 40KB và bạn đọc 40KB trong số 10MB trước tiên. Sau đó, yêu cầu 40KB tiếp theo và cứ tiếp tục như vậy. Hệ điều hành sẽ kiểm tra xem dữ liệu bạn muốn đọc đã được tải vào bộ đệm chưa. Nếu không, lỗi trang xảy ra và hệ điều hành sẽ tìm nạp dữ liệu được yêu cầu trong các trang. Một lần nữa dữ liệu này có thể được chia sẻ nếu nhiều yêu cầu thread để đọc cùng một khu vực. Bạn có thể sử dụng chính bộ nhớ cache của tệp để đọc thay vì tạo bộ đệm riêng của mình. Tuy nhiên, điều này có thể dẫn đến nhiều lỗi trang nếu tệp được đọc đồng thời nhiều lần trên nhiều vùng. Vì vậy, nó trường hợp này nó tốt hơn để có một bộ đệm riêng của kích thước tối ưu.

+0

Xin chào Vikas, bạn có thể giải thích chi tiết hơn không? Tôi rất mới với NIO. –

+0

@Grace Tôi đã đặt một biểu đồ để hiển thị cách hoạt động của nó. Tham khảo các ví dụ về tập tin bản đồ io bộ nhớ có sẵn trên web. – Drona

+0

Cảm ơn bạn đã giải thích chi tiết hơn.Trong trường hợp của tôi, tôi sẽ có một tệp khoảng 100M và khoảng 10000 khách hàng, tất cả những người này đều cần đọc toàn bộ tệp. Vì vậy, nhiều nhất tôi sẽ cần 10000 chủ đề, mỗi thread cần đệm riêng tư như 100M? Tôi tự hỏi tổng dung lượng bộ nhớ quá cao? –

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