2010-04-19 37 views
8

Như tôi đã hiểu, lớp ngoại lệ của Java chắc chắn không phải là không thay đổi (các phương pháp như initCausesetStackTrace đưa ra một số manh mối về điều đó). Vì vậy, nó là ít nhất thread-an toàn? Giả sử một trong các lớp của tôi có một trường như sau:Java: là lớp ngoại lệ có an toàn không?

private final Exception myException; 

Tôi có thể phơi bày trường này một cách an toàn cho nhiều chủ đề không? Tôi không sẵn sàng thảo luận các trường hợp cụ thể ở đâu và tại sao tình huống này có thể xảy ra. Câu hỏi của tôi là nhiều hơn về nguyên tắc: tôi có thể nói rằng một lớp học cho thấy trường của loại ngoại lệ là thread-safe?

Một ví dụ khác:

class CustomException extends Exception 
{ 
    ... 
} 

là lớp này thread-an toàn không?

Trả lời

7

Lưu ý rằng initCause()synchronizedsetStackTrace() sao chép thông số của nó và sau đó thực hiện một nhiệm vụ duy nhất.

Vì vậy, Exception thực sự dường như được triển khai với sự an toàn của luồng. Tuy nhiên, tôi sẽ cảnh giác với bất kỳ thiết kế nào mà các ngoại lệ thường được chuyển qua lại giữa các luồng (ví dụ: vì bất kỳ lý do nào khác ngoài việc xử lý một điều kiện lỗi rất nghiêm trọng). Nó chỉ cảm thấy sai.

+0

+1 cho "chỉ cảm thấy sai". – Yishai

+0

Ví dụ đầu tiên thực sự là giả thuyết.Tôi khó có thể tưởng tượng một cái gì đó như thế này trong mã của tôi :) Về ví dụ thứ hai. Tôi có thể nói trong tài liệu của tôi rằng lớp CustomException là an toàn chỉ và sau đó ngủ ngon không? –

+0

@Vilius: bạn có phải đáp ứng một số yêu cầu hare-brained nói rằng tất cả các lớp học "phải được thread-an toàn"? Và dĩ nhiên, một siêu lớp chủ đề an toàn không tự động tạo các lớp con an toàn. Nhưng vâng, tôi sẽ không đánh mất giấc ngủ này. –

0

Tôi không tin rằng bất kỳ đảm bảo an toàn chủ đề nào được cung cấp bởi các lớp Java Exception.

+0

Hiện tại (ví dụ: "trong bản sao của Throwable.java v.v. mà không gian làm việc của tôi hiện có chứa"), các lớp ngoại lệ java không đưa ra tuyên bố từ chối trách nhiệm cũng như bảo đảm liên quan đến an toàn thread/concurrency. Đây là một vấn đề lớn đối với các lớp được sử dụng rộng rãi như thế này. –

1

Đối với mặt trời của thi java 6 của Throwable

initCausesynchronized vì vậy nó đề an toàn. fillInStackTrace cũng vậy.

setStackTracekhông phải, nhưng nó tạo bản sao phòng thủ của đầu vào và sau đó gán bản sao đó. Tất nhiên, phương pháp đó là "cho các khung công tác rpc".

Miễn là trường myException của bạn là cuối cùng hoặc dễ bay hơi, bạn nên chia sẻ.

-1

Mục đích của Ngoại lệ sẽ được ném khi điều kiện được phát hiện và phát hiện khi nó được xử lý. Theo định nghĩa, những điều này sẽ xảy ra trong một chuỗi duy nhất. Nếu bạn đang chia sẻ một trường hợp ngoại lệ giữa các luồng thì bạn đang sử dụng nó cho một mục đích mà nó không được thiết kế. Làm như vậy sẽ gây nhầm lẫn cho độc giả của bạn và làm cho chương trình của bạn ít bảo trì hơn. Bạn có lẽ nên xem xét một cấu trúc thay thế cho bất cứ điều gì bạn đang sử dụng nó cho.

+1

Tôi đã nói ít nhất hai lần rằng đây là một câu hỏi giả định ... Nó thực sự không liên quan gì đến thiết kế của bất kỳ chương trình nào. –

+0

Dường như không tìm thấy lỗi nào xảy ra trên một chuỗi (công nhân) và được xử lý trên một chuỗi khác (yêu cầu)? Tôi không thấy bất kỳ lý do tại sao ngoại lệ (/ Throwables) không nên là threadsafe, vì điều này sẽ để lại các lớp con miễn phí để được threadsafe nếu đó là bắt buộc. Trường hợp xấu nhất thực sự là khi các javadocs của một lớp không đề cập đến threadafety/concurrency, vì nó để lại tất cả công việc khó khăn cho (trong trường hợp ngoại lệ, hàng triệu người dùng) ... –

1

Tôi tin rằng xuất bản một cách an toàn Throwables/Exceptions là một câu hỏi hoàn toàn hợp lệ. Nhận xét của DJClayworth rằng "nếu bạn đang chia sẻ một trường hợp ngoại lệ giữa các chủ đề thì bạn đang sử dụng nó cho một mục đích mà nó không được thiết kế" không tính đến mã quản lý tác vụ với tương lai. Nó là phổ biến cho một công nhân-thread để ném một ngoại lệ, và cho rằng ngoại lệ cần phải được xử lý bởi một chủ đề khác nhau. Ngoài tất cả các chú thích ở trên đề cập đến các phương thức đồng bộ của Throwable, Future phát hành Exceptions giữa các luồng, vì vậy tôi tin rằng có thể nói rằng đây là tính năng được mong đợi, an toàn và được hỗ trợ.

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