2008-11-19 44 views
11

Chúng tôi có một chương trình java đa luồng. Nhiều luồng sẽ ghi vào một tệp và một chuỗi sẽ đọc từ tệp đó. Tôi đang tìm kiếm một số ý tưởng thiết kế. Đồng bộ hóa có cần thiết không?Truy cập đa luồng vào tập tin

Trả lời

5

Tôi sẽ xem xét đồng bộ hóa trong trường hợp này. Hãy tưởng tượng rằng 2 chủ đề (t1 và t2) mở tập tin cùng một lúc và bắt đầu viết cho nó. Các thay đổi được thực hiện bởi luồng đầu tiên được ghi đè bởi chuỗi thứ hai vì luồng thứ hai là luồng cuối cùng để lưu các thay đổi vào tệp. Khi một chuỗi t1 đang ghi vào tệp, t2 phải chờ cho đến khi t1 hoàn thành nhiệm vụ của nó trước khi nó có thể mở nó.

Ngoài ra, nếu bạn quan tâm đến bản cập nhật mới nhất có thể của tệp, bạn nên đồng bộ hóa chuỗi ghi với chuỗi đọc tệp để nếu có bất kỳ chủ đề nào viết tệp, chuỗi đọc phải chờ.

0

Khi nhiều Chủ đề truy cập dữ liệu được chia sẻ thì cần đồng bộ hóa. Nếu nhiều chủ đề ghi vào cùng một tệp mà không có một số hình thức khóa, thì có khả năng bạn sẽ kết thúc với một vấn đề cập nhật bị mất.

Đọc không phải là vấn đề lớn trong mọi trường hợp, do đó bạn cần xem xét ... nếu chuỗi đang đọc tệp và đồng thời một luồng khác cập nhật tệp, chuỗi đọc có cần biết về thay đổi không ? Nếu vậy bạn cũng cần khóa tập tin cho chuỗi đọc.

0

Bạn cần đồng bộ hóa (khóa) nếu bạn có kết hợp của người đọc và nhà văn hoặc nhà văn và nhà văn. Nếu bạn chỉ có người đọc, bạn không cần bất kỳ đồng bộ hóa nào.

Bạn không muốn hai quy trình ghi vào cùng một tệp hoặc một quá trình ghi tệp mà người khác đang đọc.

1

Nếu bạn muốn nhiều người đọc và một người viết, bạn sẽ tìm kiếm một số Read Write Lock hoặc Đọc Viết Mutex.

Nhưng bạn muốn nhiều nhà văn và một người đọc. Làm thế nào để bạn biết những nhà văn này sẽ không ghi đè dữ liệu của nhau? Chúng bị cách ly bằng cách nào đó?

+0

Ngoài ra, hãy xem xét thực hiện hội chợ R/W-lock để ngăn người đọc khỏi việc bỏ đói các nhà văn. –

2

Nếu đang đồng bộ không quan trọng, bạn có thể để nhà văn của bạn chạy theo chủ đề riêng và cho phép các chủ đề khác xếp hàng vào tệp. Mặc dù tôi nghĩ điều đầu tiên cần xem xét là liệu việc ghi vào một tập tin có thực sự là những gì bạn muốn làm hay không. Đặc biệt trong các tình huống có lưu lượng cao, có rất nhiều đĩa I/O có thể không hiệu quả lắm.

5

FileChannel là trong chuỗi lý thuyết an toàn. Từ javadoc:

Kênh tệp an toàn để sử dụng bởi nhiều chuỗi đồng thời. Phương pháp đóng có thể được gọi bất cứ lúc nào, như được chỉ định bởi giao diện Kênh . Chỉ có một thao tác liên quan đến vị trí của kênh hoặc có thể thay đổi kích thước tệp của kênh có thể đang diễn ra tại bất kỳ thời điểm đã định nào; các nỗ lực để bắt đầu một hoạt động thứ hai như vậy trong khi hoạt động đầu tiên vẫn là đang tiến hành sẽ bị chặn cho đến khi hoạt động đầu tiên hoàn tất. Các hoạt động khác , đặc biệt là các hoạt động có vị trí rõ ràng, có thể tiến hành đồng thời; cho dù họ thực sự làm như vậy là phụ thuộc vào việc thực hiện cơ bản và do đó không được chỉ định.

Nếu bạn có thể sử dụng chúng, bạn có thể sử dụng đồng bộ hóa được cài sẵn, thay vì phải tự viết.

0

Đồng bộ hóa là cần thiết trong trường hợp này. FileChannel hữu ích cho việc ngăn chặn các tệp đang bị sửa đổi bởi các quá trình bên ngoài JVM: không phải như vậy đối với các ứng dụng bao gồm nhiều luồng ghi vào một tệp duy nhất. Từ (tiếp tục xuống) JavaDoc cho FileChannel:

Khóa tệp được giữ thay mặt cho toàn bộ máy ảo Java. Chúng là không thích hợp để kiểm soát quyền truy cập vào một tệp theo nhiều chủ đề trong số cùng một máy ảo.

Xem this post để thảo luận ngắn gọn về các chiến lược chia sẻ ghi tệp giữa các chuỗi.

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