Tại sao các luồng sinh sản trong vùng chứa Java EE không được khuyến khích?


120

Một trong những điều đầu tiên tôi học được về phát triển Java EE là tôi không nên tạo các luồng của riêng mình bên trong một vùng chứa Java EE. Nhưng khi nghĩ lại, tôi không biết lý do.

Bạn có thể giải thích rõ ràng tại sao nó được khuyến khích?

Tôi chắc chắn rằng hầu hết các ứng dụng doanh nghiệp cần một số loại công việc không đồng bộ như daemon thư, phiên nhàn rỗi, công việc dọn dẹp, v.v.

Vì vậy, nếu thực sự không nên sinh ra các chủ đề, thì cách chính xác để làm điều đó khi cần là gì?


4
Các tác vụ không đồng bộ thường được thực hiện bằng cách sử dụng nhắn tin JMS và MDB.
Ken Liu

5
Vấn đề này sẽ sớm trở thành quá khứ khi JSR 236 được triển khai trong các vùng chứa.
letmaik

5
Nó không được khuyến khích vì bất kỳ luồng thứ hai nào nên được tạo và quản lý bởi vùng chứa, để luồng sẽ có quyền truy cập vào các tài nguyên doanh nghiệp khác. Với Java EE7, có một cách chuẩn và đúng để tạo các luồng trong môi trường doanh nghiệp. Bằng cách sử dụng Concurrency Utils, bạn đảm bảo rằng luồng mới của bạn được tạo và được quản lý bởi vùng chứa, đảm bảo rằng tất cả các dịch vụ EE đều khả dụng. Ví dụ ở đây
Chris Ritchie

Có thể tìm thấy một số cách chính xác trong phối cảnh JSF / EJB tại đây: stackoverflow.com/q/6149919
BalusC

Câu trả lời:


84

Nó không được khuyến khích bởi vì tất cả các tài nguyên trong môi trường có nghĩa là được quản lý và có khả năng giám sát bởi máy chủ. Ngoài ra, phần lớn ngữ cảnh mà một luồng đang được sử dụng thường được gắn vào chính luồng thực thi. Nếu bạn chỉ bắt đầu chuỗi của riêng mình (mà tôi tin rằng một số máy chủ thậm chí sẽ không cho phép), nó không thể truy cập các tài nguyên khác. Điều này có nghĩa là bạn không thể nhận được InitialContext và thực hiện tra cứu JNDI để truy cập các tài nguyên hệ thống khác như Hệ thống dữ liệu kết nối JMS và Nguồn dữ liệu.

Có nhiều cách để làm điều này một cách "chính xác", nhưng nó phụ thuộc vào nền tảng đang được sử dụng.

Commonj WorkManager phổ biến cho WebSphere và WebLogic cũng như những người khác

Thông tin thêm tại đây

Và đây

Cũng hơi trùng lặp cái này từ sáng nay

CẬP NHẬT: Xin lưu ý rằng câu hỏi và câu trả lời này liên quan đến trạng thái của Java EE vào năm 2009, mọi thứ đã được cải thiện kể từ đó!


1
bạn không thể nhận được InitialContext và thực hiện tra cứu JNDI để truy cập các tài nguyên hệ thống khác như Hệ thống kết nối JMS và Nguồn dữ liệu. Tôi có một ứng dụng hoạt động này bằng cách tiêm các nguồn dữ liệu khi bắt đầu đề, nhưng tôi có thể phải suy nghĩ lại về cách tiếp cận này ...
rjohnston

6
Hiện đã có một cách chuẩn và đúng để tạo luồng với API Java EE cốt lõi. Bằng cách sử dụng Concurrency Utils, bạn đảm bảo rằng luồng mới của bạn được tạo và được quản lý bởi vùng chứa, đảm bảo rằng tất cả các dịch vụ EE đều khả dụng. Ví dụ ở đâyở đây
Chris Ritchie

@ChrisRitchie cảm ơn vì mẹo. nếu chỉ JBoss AS / IBM WAS hỗ trợ Java EE 7 ... :-(
asgs

1
@asgs WildFly 8 (tên mới cho JBoss AS) không hỗ trợ Java EE 7. IBM chỉ là Java EE 6 chứng nhận chứng nhận
Chris Ritchie

34

Đối với EJB, nó không chỉ không được khuyến khích mà còn bị cấm rõ ràng bởi đặc điểm kỹ thuật :

Một bean doanh nghiệp không được sử dụng các nguyên thủy đồng bộ hóa luồng để đồng bộ hóa việc thực thi nhiều trường hợp.

Đậu doanh nghiệp không được cố gắng quản lý các luồng. Hạt đậu doanh nghiệp không được cố gắng bắt đầu, dừng, tạm ngừng hoặc tiếp tục một luồng, hoặc thay đổi mức độ ưu tiên hoặc tên của một luồng. Đậu doanh nghiệp không được cố gắng quản lý các nhóm luồng.

Lý do là EJB có nghĩa là hoạt động trong một môi trường phân tán. Một EJB có thể được di chuyển từ máy này trong cụm sang máy khác. Chủ đề (và ổ cắm và các thiết bị hạn chế khác) là một rào cản đáng kể đối với tính di động này.


3
Java EE7 Concurrency Utils cung cấp một cách chính xác để tạo luồng trong môi trường doanh nghiệp. Ví dụ ở đâyở đây
Chris Ritchie

1
@Dan Bạn có thể giải thích cho tôi lý do tại sao một Thread lại là rào cản đáng kể đối với tính di động của việc di chuyển một EJB từ máy này trong máy giám sát sang máy khác không?
Geek

13

Lý do mà bạn không nên tạo ra các chuỗi của riêng mình là các chuỗi này sẽ không được vùng chứa quản lý. Vùng chứa xử lý rất nhiều thứ mà một nhà phát triển mới vào nghề có thể khó tưởng tượng. Ví dụ, những thứ như gộp luồng, phân cụm, khôi phục sự cố được thực hiện bởi vùng chứa. Khi bạn bắt đầu một chủ đề, bạn có thể mất một số trong số đó. Ngoài ra, vùng chứa cho phép bạn khởi động lại ứng dụng của mình mà không ảnh hưởng đến JVM mà nó chạy. Làm thế nào điều này có thể thực hiện được nếu có các luồng nằm ngoài tầm kiểm soát của vùng chứa?

Đây là lý do mà từ các dịch vụ bộ định thời J2EE 1.4 đã được giới thiệu. Xem này bài viết để biết chi tiết.


2
JSR 236 đã thêm các tính năng để hỗ trợ các luồng sinh sản trong Java EE 7 trở lên. Xem câu trả lời của anh chị em này của Chris Ritchie .
Basil Bourque

8

Tiện ích đồng thời cho Java EE

Hiện đã có một cách chuẩn và đúng để tạo chuỗi với API Java EE cốt lõi:

Bằng cách sử dụng Concurrency Utils, bạn đảm bảo rằng luồng mới của bạn được tạo và được quản lý bởi vùng chứa, đảm bảo rằng tất cả các dịch vụ EE đều khả dụng.

Ví dụ ở đây


2

Bạn luôn có thể yêu cầu vùng chứa bắt đầu nội dung như một phần của bộ mô tả triển khai của bạn. Sau đó, chúng có thể thực hiện bất kỳ tác vụ bảo trì nào bạn cần làm.

Theo quy định. Bạn sẽ rất vui vào một ngày nào đó bạn đã làm được :)


2

Chủ đề bị cấm trong vùng chứa Java EE theo bản thiết kế. Vui lòng tham khảo bản thiết kế để biết thêm thông tin.


2

Không có lý do thực sự để không làm như vậy. Tôi đã sử dụng Quarz với Spring trong một ứng dụng web mà không gặp sự cố. Ngoài ra, khuôn khổ đồng thời java.util.concurrentcó thể được sử dụng. Nếu bạn thực hiện xử lý chủ đề riêng của bạn, thiết lập các theads để Deamon hoặc sử dụng một thread group deamon riêng cho họ để bình chứa có thể dỡ bỏ webapp của bạn bất cứ lúc nào.

Nhưng hãy cẩn thận, phiênyêu cầu phạm vi bean không hoạt động trong các chủ đề được sinh ra! Ngoài ra, các mã khác được dựa trên ThreadLocalkhông hoạt động ngoài hộp, bạn cần phải tự mình chuyển các giá trị sang các chủ đề được tạo ra.


1

Tôi chưa bao giờ đọc thấy điều đó không được khuyến khích, ngoại trừ thực tế là nó không dễ thực hiện đúng.

Nó là một chương trình cấp thấp, và giống như các kỹ thuật cấp thấp khác, bạn phải có lý do chính đáng. Hầu hết các vấn đề đồng thời có thể được giải quyết hiệu quả hơn nhiều bằng cách sử dụng các cấu trúc tích hợp như nhóm luồng.


7
nó thực sự bị cấm bởi thông số kỹ thuật.
Ken Liu

1

Một lý do mà tôi đã tìm thấy nếu bạn sinh ra một số luồng trong EJB của bạn và sau đó bạn cố gắng dỡ bộ chứa hoặc cập nhật EJB của mình, bạn sẽ gặp sự cố. Hầu như luôn có một cách khác để làm điều gì đó mà bạn không cần Chủ đề, vì vậy chỉ cần nói KHÔNG.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.