2010-10-28 33 views
14

Trong các hệ thống đồng thời cao, có thể khó tin rằng việc sử dụng khóa của bạn là chính xác. Cụ thể, deadlocks có thể xảy ra nếu khóa được mua theo thứ tự không được mong đợi trong khi được mua theo thứ tự thích hợp trong một chuỗi khác.Xác nhận thứ tự đồng bộ hóa trong Java

Có các công cụ (ví dụ: Coverity) có thể thực hiện phân tích tĩnh trên cơ sở mã và tìm các đơn đặt hàng khóa "bất thường". Tôi muốn khám phá các tùy chọn khác để đáp ứng nhu cầu của tôi.

Có bất kỳ công cụ * trọng lượng nhẹ nào để thiết lập mã Java có thể phát hiện các trường hợp ổ khóa đang được mua lại theo thứ tự khác ngoài dự kiến ​​không? Tôi đồng ý với việc yêu cầu rõ ràng các lệnh khóa thông qua nhận xét/chú thích.

Giải pháp miễn phí và/hoặc nguồn mở được ưu tiên. Xin vui lòng cũng bình luận nếu có phương pháp không thiết bị cho vấn đề này.

* Đối với mục đích của tôi, trọng lượng nhẹ có nghĩa là ...

  • Nếu đó là thiết bị đo đạc, tôi vẫn có thể chạy chương trình của tôi với cùng sân chơi bóng chày hiệu suất. 30-50% suy thoái là chấp nhận được, tôi giả sử.
  • Tôi không phải mất nửa ngày để tương tác với công cụ này để có được "không sao". Lý tưởng nhất là tôi chỉ nên nhận thấy rằng tôi đang sử dụng nó khi có vấn đề.
  • Nếu đó là thiết bị đo, nó sẽ dễ dàng vô hiệu hóa cho môi trường sản xuất.
  • Nó không nên lộn xộn mã của tôi ở mọi câu lệnh synchronize. Như đã đề cập trước đây, tôi đồng ý với việc nhận xét/chú thích một cách rõ ràng các đối tượng hoặc các lớp của các đối tượng bị khóa với các thứ tự tương đối.
+1

... đó là lý do Mô hình diễn viên và STM ngày càng trở nên phổ biến hơn –

+0

Ai đó có phản hồi tham chiếu java.lang.Thread.holdsLock (Object) đã bị xóa ngay lập tức. Tôi không thể tự tìm ra phương pháp đó, cảm ơn con trỏ. Câu hỏi của tôi vẫn đứng vững. –

+0

bạn đã tìm thấy bất cứ điều gì tốt để làm một cái gì đó như thế? Tôi có mã phát hiện bế tắc khá phức tạp trong C++ và trong trường hợp của tôi, tôi muốn thiết lập mã Java của chúng tôi để bắt các trường hợp khóa trên C++ và/hoặc bên java có thể can thiệp lẫn nhau và dẫn đến deadlocks. – Pavel

Trả lời

3

Tôi chưa sử dụng AspectJ vì vậy không thể xác minh mức độ dễ sử dụng của AspectJ. Tôi đã sử dụng ASM để tạo một profiler mã tùy chỉnh, đây là khoảng 2 ngày làm việc. Các nỗ lực để đồng bộ hóa công cụ nên được tương tự. AspectJ sẽ nhanh hơn và dễ dàng hơn khi bạn tăng tốc với các khía cạnh.

Tôi đã triển khai theo dõi phát hiện deadlock cho máy chủ dựa trên C++ của chúng tôi. Đây là cách tôi đã làm nó:

  • Khi bao giờ có được hoặc phát hành một khóa tôi truy tìm:
    • <time> <tid> <lockid> <acquiring|releasing> <location in code>
  • thêm dấu vết này hiệu suất bị ảnh hưởng khá mạnh và không thể sử dụng trong sản xuất.
  • Vì vậy, khi một bế tắc có thể được phát hiện trong sản xuất, tôi đã sử dụng tệp nhật ký để tìm ra những gì đang xảy ra xung quanh bế tắc. Sau đó, sao chép chức năng này trong môi trường thử nghiệm với tính năng theo dõi của tôi được bật.
  • Sau đó, tôi chạy tập lệnh trên tệp nhật ký để xem liệu bế tắc có thể thực hiện được hay không.Tôi đã sử dụng một kịch bản awk, sử dụng thuật toán này:
    • Foreach dòng
      • nếu mua
        • thêm lockid vào danh sách ổ khóa hiện tại cho chủ đề
        • tiện ích này mỗi cặp khóa trong danh sách này đến một tập cặp khóa cho chủ đề này. ví dụ cho danh sách các Lock A -> Lock B -> Lock C tạo ra các cặp (Lock A, Lock B), (Lock A, Lock C), (Lock B, Lock C)
      • nếu phát hành
        • loại bỏ lockid hiện từ đuôi của danh sách cho chủ đề
    • này Đối với mỗi lần tìm kiếm cặp khóa tất cả các chủ đề khác cho cặp khóa đảo ngược, mỗi trận đấu là một bế tắc tiềm ẩn để in các cặp và chủ đề bị ảnh hưởng
    • Thay vì làm cho thuật toán thông minh hơn thì tôi đã kiểm tra e khóa mua lại để xem nếu nó là một bế tắc thực sự.

Tôi đã làm điều này sau khi thất bại trong việc tìm ra nguyên nhân của một bế tắc cho một số ngày, phải mất hơn một vài ngày để thực hiện và một vài giờ để tìm ra bế tắc.

Nếu bạn đang xem xét phương pháp này trong Java điều cần xem xét là:

  • Bạn chỉ sử dụng synchronized để bảo vệ phần quan trọng của bạn? Bạn có đang sử dụng các lớp trong java.lang.concurrent không? (chúng có thể yêu cầu xử lý/thiết bị đặc biệt)
  • Việc in vị trí mã với các khía cạnh/ASM dễ dàng như thế nào? Tôi đã sử dụng __FILE____LINE__ bằng C++. ASM sẽ cung cấp cho bạn tên lớp, tên phương thức và chữ ký.
  • Bạn không thể sử dụng các khóa được sử dụng để bảo vệ truy tìm/ghi nhật ký của bạn.
  • Bạn có thể hợp lý hóa công cụ của mình nếu bạn sử dụng tệp nhật ký cho mỗi luồng và lưu trữ cục bộ luồng cho đối tượng tệp.
  • Làm thế nào để bạn xác định duy nhất các đối tượng mà bạn đồng bộ hóa? Có thể toString() và System.identityHashCode() sẽ là đủ, nhưng có thể yêu cầu nhiều hơn. Tôi đã sử dụng địa chỉ của đối tượng trong C++.
+0

Đây là một giải pháp hợp lý, nhưng tôi đã hy vọng có một công cụ có thể làm tất cả công việc đó cho tôi. Sẽ xem xét ASM nhiều hơn - cảm ơn bạn. –

0

Không đưa bạn đến đó, nhưng khởi đầu tốt là sử dụng JCIP annotationsFindBugs phát hiện một vài điều.

+0

Trừ khi tôi đang thiếu một cái gì đó, FindBugs không có bất kỳ kiểm tra cho màn hình (khối đồng bộ) đặt hàng. –

+0

@ Derrick Rice: Tôi đã không biết về bất kỳ công cụ nào làm chính xác những gì OQ đã hỏi, nhưng cung cấp một cái gì đó trong vùng lân cận ... – andersoj

1

Bạn có thể sử dụng AspectJ, tương đối dễ dàng để tìm hiểu và sẽ cho phép bạn thiết lập cách tùy chỉnh và đơn giản hóa của riêng bạn theo dõi chủ đề của bạn và bất kỳ khóa nào họ truy cập.

+1

Cảm ơn. Tôi đã làm theo ý tưởng này cho đến khi tôi nhận được bài báo này, "Một điểm tham gia cho khối đồng bộ trong AspectJ": http://www.cs.man.ac.uk/~xic/SBJP_AspectJ.pdf –

+0

Giấy đẹp. Cảm ơn bạn đã chia sẻ liên kết và xin lỗi nếu những bất lợi không làm cho nó có thể sử dụng được trong tình huống của bạn. –

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