2012-06-25 42 views
10

Tôi đang tìm một cách hiệu quả để triển khai cấu trúc cây đồng thời. Nếu điều đó giúp, giả sử rằng tôi có nhiều quyền truy cập đọc nhiều hơn thay đổi cấu trúc.Cây đồng thời hiệu quả

Cây nên hỗ trợ các hoạt động này:

  • Thêm và xóa các nút
  • Sắp xếp các chi nhánh mỗi khi một nút mới được chèn
  • lặp qua tất cả các nút (không ConcurrentModificationException)
  • Tra cứu một phần tử theo đường dẫn

Trả lời

6

Hãy xem tại địa chỉ: Concurrent-Trees trên mã Google kiếm một cách để thay đổi cơ cấu cây giống mà không cần khóa.

Dự án cung cấp các cây phối trộn đồng thời và hậu tố cho Java. Chúng hỗ trợ đọc và ghi đồng thời, và đọc là không có khóa. Nó hoạt động bằng cách áp dụng các bản vá lỗi cho cây một cách nguyên tử. Mặc dù các loại cây này có thể không chính xác những gì bạn muốn, nhưng cách tiếp cận bằng cách sử dụng "vá" như được mô tả trong TreeDesign hữu ích cho bất kỳ loại cấu trúc giống cây nào.

Cây được dùng cho các trường hợp sử dụng đa số đọc đồng thời cao, trong đó có một chủ đề nền có thể chèn hoặc xóa các mục từ cây trong khi nhiều chủ đề tiền cảnh sẽ tiếp tục di chuyển nó không bị thay đổi bởi các sửa đổi.

+0

Điều này thật thú vị nhưng vô dụng trong trường hợp sử dụng của tôi. Cây của tôi là cây thật (cấu trúc cha-con), không phải là bản đồ có giá trị khóa. –

+1

Tôi muốn tránh sử dụng các từ như "vô dụng". Câu trả lời này đã được đóng góp để giúp bạn tự nguyện. Nếu bạn đang tìm kiếm các cây đồng thời đọc chủ yếu, các thuật toán không có khóa có thể là một cách tốt để đi. Cây radix có thể không chính xác những gì bạn đang tìm kiếm, nhưng như tôi đã đề cập, cách tiếp cận vá nguyên tử mà tôi liên kết, có thể được áp dụng cho bất kỳ loại cây nào để đọc miễn phí, ngay cả khi bạn đang có kế hoạch viết riêng cây. Vô tình cây radix rõ ràng là cây, có cấu trúc cha-con. – npgall

+0

+1 Tôi đã cải thiện từ ngữ để làm cho ý định của bạn rõ ràng hơn. –

3

Bạn có thể sử dụng khóa người đọc trong cấu trúc của mình, tôi n một cách mà nhiều luồng có thể đọc đồng thời nhưng chỉ có một luồng tại một thời điểm có thể sửa đổi nó. Nếu một số chủ đề cố gắng sửa đổi cấu trúc, nó không thể làm điều đó cho đến khi tất cả người đọc đọc xong. Nếu một chủ đề muốn đọc nó chỉ có thể nếu một người viết chưa hoạt động, hoặc nó là trên shedule thực hiện một số sửa đổi. Có lẽ nhìn vào điều này có thể giúp:

http://docs.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/locks/ReentrantReadWriteLock.html

+0

+1 Đối với khóa đọc/ghi – mishadoff

1

ý tưởng cơ bản với Read/Write khóa

Đối với tất cả các phương pháp viết sử dụng sau thành ngữ:

someWriteMethod(){ 
    writeLock.lock(); 
    // logic 
    writeLock.unlock(); 
} 

Đối với tất cả đọc phương pháp sử dụng tương tự mã:

someReadMethod(){ 
    readLock.lock(); 
    // logic 
    readLock.unlock(); 
} 
  • Nếu ít nhất một phương pháp thực hiện viết, không ai có thể có được khóa đọc hoặc ghi.
  • Nếu ít nhất một phương pháp thực hiện việc đọc, bất kỳ số lượng chuỗi nào đều có thể đọc được khóa.
  • Nếu ít nhất một phương pháp thực hiện việc đọc, không ai có thể lấy khóa ghi.

Lưu ý, nếu mã của bạn (thay thế nhận xét logic ở trên) có thể ném ngoại lệ, hãy đảm bảo bạn giải phóng khóa trước khi thoát khỏi phương pháp trong phần cuối cùng.

+0

Khóa đọc ghi có một nhược điểm: Bạn không thể "nâng cấp" đọc vào khóa ghi, vì vậy bạn cần biết trước liệu thao tác của bạn có sửa đổi cây không. Vì vậy, đó sẽ cần hai vòng lặp, nơi người ta có thể khóa quá nhiều. –

+0

Tôi giả sử rằng sử dụng cây bạn biết trước những gì hoạt động sửa đổi cây của bạn, phải không? – mishadoff

+0

Khi tôi hỏi cây cho một trình lặp, phương thức tạo trình lặp không thể biết tôi có gọi remove() hay không. –

5

Cấu trúc Java gần nhất với những gì bạn cần là ConcurrentSkipListSet (hoặc có thể ConcurrentSkipListMap).


Nếu bạn cần thêm phương pháp tùy chỉnh, bạn có thể triển khai cấu trúc cây tùy chỉnh nếu bạn có khóa đọc ghi phân cấp. Dưới đây là một answerto một câu hỏi tương tự về cách triển khai một reentrant read-write lock: https://stackoverflow.com/a/6154873/272388

+1

CSLM không thực sự gần gũi. Nó là một * bản đồ được sắp xếp * có ít để làm với một cấu trúc cây. Vì vậy, nó chỉ chia sẻ một thuộc tính chung với 'TreeMap' ở chỗ nó là một bản đồ được sắp xếp - không có liên quan ở đây. –

+0

Đó là lý do tại sao có phần thứ hai của câu trả lời vì tôi không biết bất kỳ cấu trúc cây nào được bao gồm trong Java hỗ trợ tất cả các hoạt động này. Ngoài ra, CSLM có thể đủ cho một số trường hợp tương tự. – Kru

+1

Kru vẫn chính xác: Đó là cấu trúc dữ liệu duy nhất trong thời gian chạy chính thức gần nhất với vấn đề của tôi. Tôi có thể xây dựng cây bằng cách sử dụng các khóa ConcurrentSkipListMaps + lồng nhau. –

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