2010-02-19 4 views
6

Tiêu đề hủy không được chấp nhận trong Java (và không được thực hiện theo javadoc), và ngắt nó chỉ là một gợi ý mà trên luồng dự kiến ​​sẽ thoát, nhưng có thể không làm như vậy. (Không cung cấp bất kỳ cách nào để giết một sợi bên trong J VM là một thiết kế đáng lo ngại, nhưng câu hỏi của tôi không được thiết kế liên quan.)Máy chủ ứng dụng java có thể phá hủy đề tài không? Nếu có, làm thế nào?

Làm thế nào để các máy chủ ứng dụng Java dỡ bỏ các ứng dụng? Họ có thể bằng cách nào đó để tiêu diệt các chủ đề của một ứng dụng đang được dỡ xuống không? Nếu có, làm thế nào? Nếu không, thì một chuỗi duy nhất của ứng dụng được triển khai với vòng lặp vô hạn có thể làm giảm toàn bộ máy chủ ứng dụng mà không có bất kỳ khả năng can thiệp nào?

Rất tiếc, tôi không viết các trường hợp kiểm tra cho việc này, nhưng tôi muốn biết điều gì đang thực sự xảy ra ở đó.

Trả lời

2

Bạn không được phép tạo chuỗi của riêng mình bên trong máy chủ ejb. Nó không phải là không phổ biến để sinh ra các chủ đề trong một container web (ví dụ như tomcat), mặc dù bạn thực sự nên suy nghĩ cẩn thận về việc đó - và chắc chắn để quản lý vòng đời của những chủ đề đó.

+1

Máy chủ ứng dụng có thể làm gì khi một bean có vòng lặp vô hạn "được triển khai" theo một trong các phương pháp của nó? Toàn bộ máy chủ ứng dụng cần được khởi động lại ở cấp hệ điều hành? – sibidiba

+1

@sibidiba - Có. Đó là về nó. –

11

Không cung cấp bất kỳ cách nào để tiêu diệt một sợi bên trong máy ảo J VM là một thiết kế đáng lo ngại, nhưng câu hỏi của tôi không liên quan đến thiết kế.

Vì câu hỏi thực sự của bạn đã được trả lời, tôi sẽ giải quyết câu được trích dẫn ở trên.

Lịch sử là các nhà thiết kế Java ban đầu đã làm cố gắng giải quyết vấn đề giết và đình chỉ chuỗi, nhưng chúng chạy vào một vấn đề cơ bản mà họ không thể giải quyết trong ngữ cảnh của ngôn ngữ Java.

Vấn đề ở đây là bạn không thể tiêu diệt một cách an toàn luồng có thể thay đổi dữ liệu được chia sẻ theo kiểu không nguyên tử hoặc có thể đồng bộ hóa với nhau bằng cách sử dụng cơ chế chờ/thông báo. Nếu bạn thực hiện giết chết chuỗi trong ngữ cảnh này, bạn kết thúc với một phần cập nhật cho cấu trúc dữ liệu và các chủ đề khác đang chờ thông báo rằng sẽ không bao giờ đến. Nói cách khác, giết chết một sợi có thể để phần còn lại của ứng dụng ở trạng thái không chắc chắn và bị hỏng.

Các ngôn ngữ/thư viện khác (ví dụ: C, C++, C#) cho phép bạn xóa các chủ đề bị cùng một vấn đề tôi mô tả ở trên, ngay cả khi các thông số kỹ thuật/sách có liên quan không rõ ràng. Trong khi có thể giết chủ đề, bạn phải thực sự cẩn thận trong việc thiết kế và thực hiện toàn bộ ứng dụng để thực hiện việc này một cách an toàn. Nói chung nó là quá khó để có được quyền.

Vì vậy, (giả thuyết) điều gì sẽ làm cho việc tiêu diệt chuỗi an toàn trong Java? Dưới đây là một số ý tưởng:

  • Nếu JVM của bạn đã thực hiện Cô lập, bạn có thể khởi chạy tính toán mà bạn có thể muốn giết ở trẻ em Cô lập. Vấn đề là một cô lập được thực hiện đúng cách chỉ có thể giao tiếp với các chủng phân lập khác bằng cách truyền thông điệp, và chúng thường tốn kém hơn nhiều để sử dụng.

  • Sự cố trạng thái có thể chia sẻ được chia sẻ có thể được giải quyết bằng cách cấm hoàn toàn đột biến hoặc bằng cách thêm giao dịch vào mô hình thực thi Java. Cả hai điều này về cơ bản sẽ thay đổi Java.

  • Vấn đề chờ/thông báo có thể được giải quyết bằng cách thay thế bằng cơ chế chuyển tiếp hoặc thông báo cho phép chuỗi "khác" được thông báo rằng chuỗi tương tác đã biến mất. Chủ đề "khác" sẽ vẫn cần được mã hóa để khôi phục từ này.

EDIT - Để phản hồi lại các cam kết.

Lỗi bế tắc đột ngột không phải là vấn đề đối với thread.destroy() vì nó được thiết kế để giải phóng (ngắt) tất cả các mutex thuộc sở hữu của chuỗi đã bị hủy. Vấn đề là không có gì đảm bảo rằng cấu trúc dữ liệu được bảo vệ bởi mutex sẽ ở trạng thái sane sau khi khóa bị hỏng.

Nếu tôi hiểu lịch sử của chủ đề này một cách chính xác, Thread.suspend(), Thread.delete() và vân vân thực sự đã vấn đề gây ra trong thế giới thực Java 1.0 ứng dụng. Và những vấn đề này rất nghiêm trọng và rất khó để các nhà văn ứng dụng giải quyết, rằng các nhà thiết kế JVM đã quyết định rằng khóa học tốt nhất là không dùng các phương thức. Đây sẽ không phải là một quyết định dễ dàng để thực hiện.

Bây giờ, nếu bạn dũng cảm, bạn thực sự có thể sử dụng các phương pháp này. Và chúng có thể thực sự an toàn trong một số trường hợp. Nhưng việc xây dựng một ứng dụng xung quanh các phương pháp không được chấp nhận không phải là thực hành kỹ thuật phần mềm âm thanh.

+1

Điều này, lần một trăm –

+0

Tôi không phải là một nhà thiết kế JVM hardcore, nhưng tất cả các đối số về giao dịch dường như quá nhiều tạo nên. Vô hiệu hóa tính năng này đã không làm cho Java bế tắc dễ bị. Tôi chỉ đơn giản là làm một khóa, và không bao giờ mở khóa. Cho phép thread.destroy() thực sự sẽ giới thiệu một khả năng mới của deadlocks, nhưng tại sao trên thế giới này tôi không được phép giết một luồng không chứa tài nguyên _any_ (theo lập trình viên hoặc JVM)? – sibidiba

+1

@sibida: trở lại trong những ngày, nhiều năm trước, tôi đã tiếp tục sử dụng các phương pháp không dùng nữa để tiêu diệt chủ đề. Tôi biết rằng nó 'an toàn' để phá hủy và tôi chưa bao giờ gặp vấn đề gì ... * NHƯNG * Tôi đã ngừng làm một việc như vậy : luôn có cách để 'hủy' một chuỗi mà bạn có quyền kiểm soát, bằng cách đóng một số ổ cắm, bằng cách đặt một viên thuốc độc vào hàng đợi chặn, bằng cách đặt một số 'boolean' thành 'true', tôi đã từng nghĩ 'phá hủy' thực sự cần thiết và tiếp tục làm điều đó, nhưng bây giờ tôi không còn nữa. Luôn luôn có một cách khác đúng không? Điều gì sẽ là một trường hợp mà sẽ không có cách nào để 'sạch' hủy bỏ một sợi? – SyntaxT3rr0r