Tôi đang cố gắng sử dụng cả hai InheritableThreadLocal
và một ThreadPoolExecutor
.Sử dụng InheritableThreadLocal với ThreadPoolExecutor - hoặc - một ThreadPoolExecutor không sử dụng lại các chủ đề
Điều này bị hỏng do ThreadPoolExecutor
sử dụng lại các chủ đề cho mỗi nhóm (sau cùng là hồ bơi), nghĩa là InheritableThreadLocal
không hoạt động như mong đợi. Bây giờ vấn đề có vẻ hiển nhiên đối với tôi, nhưng nó đặc biệt khó hiểu để theo dõi.
Tôi sử dụng InheritableThreadLocal
để mỗi một số quy trình cấp cao nhất có kết nối cơ sở dữ liệu riêng cho chính nó và mọi quy trình phụ mà nó sinh ra. Tôi không chỉ sử dụng một nhóm kết nối được chia sẻ vì mỗi quy trình cấp cao nhất sẽ thực hiện nhiều bước với kết nối của nó trước khi cam kết với cơ sở dữ liệu và/hoặc chuẩn bị rất nhiều PreparedStatements được sử dụng nhiều lần.
Tôi sử dụng số chia sẻ ThreadPoolExecutor
giữa các quy trình cấp cao nhất này vì có một số hành vi nhất định cần được kiểm soát. ví dụ. Mặc dù tôi có thể có 4 quy trình cấp cao nhất đang chạy, tôi chỉ có thể có bất kỳ một quy trình nào bằng văn bản cho cơ sở dữ liệu tại một thời điểm (hoặc hệ thống cần phải truy cập vào một số tài nguyên được chia sẻ khác). Vì vậy, tôi sẽ có quy trình cấp cao nhất tạo một Runnable
và gửi nó đến số ThreadPoolExecutor
được chia sẻ để đảm bảo rằng không quá một (hoặc hai hoặc ba trường hợp có thể) đang chạy cùng một lúc trên toàn bộ hệ thống.
Vấn đề là do ThreadPoolExecutor
sử dụng lại chủ đề của nó cho các hồ bơi, InheritableThreadLocal
đang chọn giá trị ban đầu được chạy trong nhóm đó thay vì giá trị trong quy trình cấp cao nhất đã gửi Runnable đến ThreadPoolExecutor
.
Có cách nào để buộc các hồ bơi công nhân trong
ThreadPoolExecutor
sử dụng giá trịInheritableThreadLocal
đó là trong bối cảnh của quá trình đó tạo ra Runnable hơn là trong bối cảnh tái sử dụng hồ bơi thread?Ngoài ra, có việc triển khai
ThreadPoolExecutor
nào tạo chủ đề mới mỗi khi khởi động Runnable mới không? Đối với mục đích của tôi, tôi chỉ quan tâm đến việc gating số lượng các chuỗi chạy đồng thời với một kích thước cố định.Có giải pháp hoặc đề xuất nào khác mà mọi người có để tôi thực hiện những gì tôi đã mô tả ở trên không?
(Trong khi tôi nhận ra tôi có thể giải quyết vấn đề bằng cách thông qua xung quanh việc kết nối cơ sở dữ liệu từ lớp học để subthread để subthread như một số loại xe đạp cộng đồng, tôi muốn tránh điều này.)
Có một câu hỏi trước trên StackOverflow, InheritableThreadLocal and thread pools, cũng giải quyết vấn đề này. Tuy nhiên, giải pháp cho vấn đề đó dường như là một trường hợp sử dụng kém cho InheritableThreadLocal, mà tôi không nghĩ là áp dụng cho tình huống của tôi.
Cảm ơn mọi ý tưởng.
Tôi đã không sử dụng Semaphores vì vậy tôi sẽ xem xét điều này. Chúng tôi sử dụng rất nhiều tính năng khác của Executors (Futures, timeouts,…) nhưng tôi có thể làm điều đó với Semaphores hoặc tôi có thể sử dụng một người thực hiện thường xuyên (không phải thread pool) cùng với semaphores để có được mọi thứ tôi cần. Cảm ơn. –
Đây là cách đi đúng đắn. Sử dụng Semaphores và FutureTasks là một mô hình đại diện hơn cho những gì chúng tôi muốn làm. Sau khi thay đổi mã đã được đơn giản hóa rất nhiều, đó luôn luôn là một dấu hiệu tốt. Plus nó giải quyết bất kỳ vấn đề InheritableThreadLocal. –