Lợi thế của việc sử dụng ExecutorService
đối với các chủ đề chạy qua một số Runnable
vào hàm tạo Thread
là gì?Ưu điểm của việc sử dụng ExecutorService là gì?
Trả lời
ExecutorService
tóm tắt nhiều sự phức tạp liên quan đến các tóm tắt cấp thấp hơn như raw Thread
. Nó cung cấp các cơ chế để bắt đầu, đóng, gửi, thực hiện và chặn một cách an toàn khi chấm dứt thành công hoặc đột ngột các tác vụ (được biểu thị là Runnable
hoặc Callable
).
Từ JCiP Mục 6.2, trực tiếp từ miệng của ngựa:
Executor
có thể là một giao diện đơn giản, nhưng nó là cơ sở cho một khuôn khổ linh hoạt và mạnh mẽ để thực hiện nhiệm vụ không đồng bộ có hỗ trợ một loạt các nhiệm vụ chính sách thực thi. Nó cung cấp một phương tiện tiêu chuẩn để tách gửi nhiệm vụ từ thực hiện tác vụ, mô tả các tác vụ làRunnable
. Việc triển khaiExecutor
cũng cung cấp hỗ trợ vòng đời và móc để thêm thu thập số liệu thống kê, quản lý ứng dụng và theo dõi. ... Sử dụngExecutor
thường là con đường dễ nhất để thực hiện thiết kế của người tiêu dùng sản xuất trong ứng dụng của bạn.
Thay vì dành thời gian thực hiện (thường không chính xác và nỗ lực lớn) cơ sở hạ tầng cơ sở cho song song, khung j.u.concurrent
cho phép bạn tập trung vào cấu trúc nhiệm vụ, phụ thuộc, song song tiềm năng. Đối với một loạt các ứng dụng đồng thời, việc xác định và khai thác các ranh giới nhiệm vụ là rất đơn giản và sử dụng j.u.c
, cho phép bạn tập trung vào tập hợp con nhỏ hơn nhiều các thách thức đồng thời thực sự có thể yêu cầu các giải pháp chuyên biệt hơn.
Ngoài ra, mặc dù giao diện soạn sẵn và cảm nhận, các Oracle API page summarizing the concurrency utilities bao gồm một số đối số thực sự vững chắc cho việc sử dụng họ, không kém phần quan:
phát triển có nhiều khả năng đã hiểu các thư viện chuẩn lớp học, vì vậy không có cần phải tìm hiểu API và hành vi của các thành phần đồng thời . Ngoài ra, các ứng dụng đồng thời còn cách xa đơn giản hơn để gỡ lỗi khi chúng được xây dựng trên các thành phần đáng tin cậy, được thử nghiệm tốt.
question on SO hỏi về một cuốn sách hay, câu trả lời ngay lập tức là JCiP. Nếu bạn chưa có, hãy lấy cho mình một bản sao. Cách tiếp cận toàn diện để đồng thời trình bày ở đó cũng vượt ra ngoài câu hỏi này, và sẽ giúp bạn tiết kiệm rất nhiều đau khổ trong thời gian dài.
Một lợi thế mà tôi thấy là trong việc quản lý/lên lịch một số chuỗi. Với ExecutorService, bạn không cần phải viết trình quản lý luồng của riêng mình có thể bị lỗi với các lỗi. Điều này đặc biệt hữu ích nếu chương trình của bạn cần chạy nhiều luồng cùng một lúc. Ví dụ, bạn muốn thực hiện hai luồng cùng một lúc, bạn có thể dễ dàng làm điều đó như thế này:
ExecutorService exec = Executors.newFixedThreadPool(2);
exec.execute(new Runnable() {
public void run() {
System.out.println("Hello world");
}
});
exec.shutdown();
Ví dụ có thể tầm thường, nhưng cố gắng nghĩ rằng "hello world" dòng chứa một hoạt động nặng và bạn muốn hoạt động đó chạy trong một vài luồng cùng một lúc để cải thiện hiệu suất của chương trình.Đây chỉ là một ví dụ, vẫn còn nhiều trường hợp mà bạn muốn lên lịch hoặc chạy một số luồng và sử dụng ExecutorService làm trình quản lý luồng của bạn.
Để chạy một chuỗi duy nhất, tôi không thấy bất kỳ lợi thế rõ ràng nào khi sử dụng ExecutorService.
Để chạy tác vụ bằng cách triển khai giao diện Runnable
, chúng tôi phải tạo đối tượng của Thread
như new thread(RunnableObject).start()
. Nhưng chúng tôi biết rằng việc tạo chuỗi có chi phí riêng và được lưu trữ trong bộ nhớ Stack và Heap. Nó rất tốn kém để tạo một đối tượng chuỗi chỉ để chạy tác vụ trong chuỗi riêng biệt.
Executors
khuôn khổ (java.util.concurrent.Executor)
, được phát hành bởi Java 5 trong gói java.util.concurrent
được sử dụng để chạy các đối tượng chuỗi Runnable mà không cần tạo đối tượng Thread.
"Khung Executor
là khuôn khổ để chuẩn hóa yêu cầu, lập lịch biểu, thực thi và kiểm soát các tác vụ không đồng bộ theo một bộ chính sách thực thi".
Dưới đây là một số lợi ích:
- dịch vụ Executor quản lý chủ đề theo cách không đồng bộ
- Sử dụng callable để có được kết quả trở lại sau khi kết thúc bài.
- Quản lý phân bổ công việc vào chủ đề miễn phí và làm việc bán lại hoàn thành từ chủ đề cho phân công công việc mới tự động
- ngã ba - tham gia khuôn khổ cho xử lý song song
- thông tin liên lạc tốt hơn giữa các chủ đề
- invokeAll và invokeAny cho kiểm soát nhiều hơn để chạy bất kỳ hoặc tất cả các chủ đề cùng một lúc
- tắt máy cung cấp khả năng hoàn thành tất cả các công việc được chỉ định theo chủ đề
- Dịch vụ thực thi theo lịch trình cung cấp các phương pháp để tạo lặp lại các cuộc gọi chạy và các cuộc gọi Hy vọng nó sẽ giúp bạn
Không phải là "Tương lai" ở điểm thứ hai thay vì có thể gọi được? Tương lai là từ nơi chúng ta có thể lấy kết quả/Giá trị sau khi hoàn thành chuỗi. – AmitG
Có như ví dụ. Tương lai
Trước java phiên bản 1.5, Chủ đề/Runnable được thiết kế cho hai dịch vụ riêng biệt
- Đơn vị công tác
- Thi hành mà đơn vị làm việc
ExecutorService tách riêng những hai dịch vụ bằng cách chỉ định Runnable/Callable làm đơn vị công việc và Người thực thi làm cơ chế thực hiện (với vòng đời) đơn vị công việc
ExecutorService cũng cho phép truy cập vào FutureTask sẽ trở lại lớp gọi điện thoại kết quả của một tác vụ nền sau khi hoàn thành. Trong trường hợp triển khai có thể gọi
public class TaskOne implements Callable<String> {
@Override
public String call() throws Exception {
String message = "Task One here. . .";
return message;
}
}
public class TaskTwo implements Callable<String> {
@Override
public String call() throws Exception {
String message = "Task Two here . . . ";
return message;
}
}
// from the calling class
ExecutorService service = Executors.newFixedThreadPool(2);
// set of Callable types
Set<Callable<String>>callables = new HashSet<Callable<String>>();
// add tasks to Set
callables.add(new TaskOne());
callables.add(new TaskTwo());
// list of Future<String> types stores the result of invokeAll()
List<Future<String>>futures = service.invokeAll(callables);
// iterate through the list and print results from get();
for(Future<String>future : futures) {
System.out.println(future.get());
}
Các giới hạn sau đây từ chủ đề truyền thống được khắc phục bằng khung công tác (được xây dựng trong khuôn khổ Thread Pool).
- Quản lý tài nguyên kém tức là tiếp tục tạo tài nguyên mới cho mọi yêu cầu. Không có giới hạn để tạo tài nguyên.Sử dụng khung công tác Executor, chúng tôi có thể tái sử dụng các tài nguyên hiện có và đặt giới hạn về việc tạo tài nguyên.
- Không mạnh mẽ: Nếu chúng tôi tiếp tục tạo chủ đề mới, chúng tôi sẽ nhận được
StackOverflowException
ngoại lệ do đó JVM của chúng tôi sẽ gặp sự cố. - Tạo thời gian trên không: Đối với mỗi yêu cầu, chúng tôi cần tạo tài nguyên mới. Để tạo tài nguyên mới là tốn thời gian. tức là tác vụ Tạo chuỗi>. Sử dụng khung công tác Executor, chúng ta có thể xây dựng trong Thread Pool.
Lợi ích của Chủ đề Pool
Sử dụng Chủ đề Pool giảm thời gian phản ứng bằng cách tránh tạo thread trong yêu cầu hoặc xử lý công việc.
Sử dụng Thread Pool cho phép bạn thay đổi chính sách thực thi của mình nếu cần. bạn có thể chuyển từ chuỗi đơn thành nhiều chuỗi chỉ bằng cách thay thế triển khai ExecutorService.
Chủ đề Bể bơi trong ứng dụng Java tăng tính ổn định của hệ thống bằng cách tạo một số lượng cấu hình luồng được quyết định dựa trên tải hệ thống và tài nguyên có sẵn.
Thread Pool giải phóng nhà phát triển ứng dụng khỏi công cụ quản lý luồng và cho phép tập trung vào logic nghiệp vụ.
Có thực sự đắt tiền để tạo ra một chủ đề mới?
Là điểm chuẩn, tôi vừa tạo 60.000 chủ đề với Runnable
s với các phương thức trống rỗng run()
. Sau khi tạo ra mỗi thread, tôi gọi phương thức start(..)
của nó ngay lập tức. Việc này mất khoảng 30 giây hoạt động CPU mạnh. Các thử nghiệm tương tự đã được thực hiện để đáp ứng với this question. Tóm tắt của những người là nếu các chủ đề không hoàn thành ngay lập tức, và một số lượng lớn các chủ đề tích cực tích lũy (một vài nghìn), sau đó sẽ có vấn đề: (1) mỗi thread có một ngăn xếp, vì vậy bạn sẽ hết bộ nhớ , (2) có thể có giới hạn về số lượng chủ đề cho mỗi quá trình mà hệ điều hành áp đặt, nhưng not necessarily, it seems. Vì vậy, theo tôi có thể thấy, nếu chúng ta đang nói về việc khởi chạy 10 chủ đề mỗi giây và tất cả đều kết thúc nhanh hơn so với những chủ đề mới bắt đầu và chúng tôi có thể đảm bảo rằng tỷ lệ này sẽ không bị vượt quá quá nhiều , sau đó ExecutorService không cung cấp bất kỳ lợi thế cụ thể nào về hiệu suất hiển thị hoặc độ ổn định. (Mặc dù nó vẫn có thể làm cho nó thuận tiện hơn hoặc dễ đọc hơn để thể hiện một số ý tưởng đồng thời nhất định trong mã.) Mặt khác, nếu bạn có thể lên lịch hàng trăm hoặc hàng nghìn tác vụ mỗi giây, cần thời gian để chạy, bạn có thể gặp phải các vấn đề lớn đi thẳng. Điều này có thể xảy ra bất ngờ, ví dụ: nếu bạn tạo các luồng để đáp ứng các yêu cầu tới một máy chủ, và có sự tăng đột biến về cường độ các yêu cầu mà máy chủ của bạn nhận được. Nhưng ví dụ: một chủ đề đáp ứng mọi sự kiện đầu vào của người dùng (nhấn phím, chuyển động của chuột) có vẻ hoàn toàn ổn, miễn là các tác vụ ngắn gọn.
- 1. Ưu điểm của việc sử dụng sai sót là gì?
- 2. Ưu điểm của việc sử dụng Automapper là gì?
- 3. Ưu điểm của việc sử dụng các đặc điểm trên các lớp trừu tượng là gì?
- 4. Ưu điểm và nhược điểm của việc sử dụng ARC là gì?
- 5. Ưu điểm và nhược điểm của việc sử dụng boost :: iterator_facade là gì?
- 6. Ưu điểm và nhược điểm của việc sử dụng Phonegap và Titanium là gì?
- 7. Ưu điểm/nhược điểm của việc sử dụng bộ ria mép với Backbone.js là gì?
- 8. Ưu điểm của việc tải DLL động là gì?
- 9. Ưu điểm/nhược điểm của việc sử dụng SRVANY so với việc tạo một dịch vụ Windows là gì?
- 10. Ưu điểm của việc sử dụng SVN trên CVS là gì?
- 11. Ưu điểm của việc sử dụng giao dịch tổng hợp với pgbouncer là gì?
- 12. Ưu điểm của việc sử dụng thư viện JavaScript Sizzle là gì?
- 13. Ưu và nhược điểm của việc sử dụng configChanges = "orientation" cho thiết bị Android là gì?
- 14. Ưu và nhược điểm của việc sử dụng git-svn là gì?
- 15. Ưu điểm của việc sử dụng mối quan hệ một-một là gì? (MySQL)
- 16. Ưu điểm của việc sử dụng thư viện C++ Boost là gì?
- 17. Ưu điểm của việc sử dụng Prolog trên các ngôn ngữ khác là gì?
- 18. Ưu và khuyết điểm của việc sử dụng công cụ tạo mẫu như Jade là gì?
- 19. Ưu điểm của việc sử dụng EJB so với POJO là gì?
- 20. Ưu điểm của việc sử dụng Ruby NArray trên Array là gì?
- 21. Ưu điểm thực sự của việc sử dụng các khối trong Objective-C là gì?
- 22. Ưu và khuyết điểm của việc sử dụng cờ enum là gì?
- 23. Ưu điểm của NSBinaryStoreType là gì?
- 24. Ưu điểm của Apache Wicket là gì?
- 25. Điểm của việc sử dụng UDP với NIO là gì?
- 26. Ưu điểm của việc sử dụng chuyển tiếp
- 27. Ưu điểm của việc sử dụng Gọi lại Hibernate?
- 28. Ưu điểm của việc sử dụng định kiến mùa xuân?
- 29. Ưu điểm của việc sử dụng Doctrine cho PHP?
- 30. Ưu điểm/Nhược điểm của việc sử dụng phương pháp Declarative so với Programme với ASP.Net là gì?
Nó không phải là exec.execute (Runnable mới() ..? – devnull
Hoặc là okay kể từ khi chủ đề thực hiện Runnable.Đối với trường hợp đơn giản, Runnable nên được đầy đủ – Manny
Tôi thực sự không nghĩ rằng có bất kỳ điểm nào trong việc tạo ra một ' Chủ đề' khi tất cả những gì bạn cần là 'Runnable' ... bạn thậm chí không bắt đầu 'Thread', vì vậy nó chỉ thêm nhầm lẫn và hành lý không cần thiết. – ColinD