2013-08-25 24 views
18

sự khác biệt giữashutdown và awaitTermination mà cuộc gọi đầu tiên có bất kỳ sự khác biệt?

ExecutorService eService = Executors.newFixedThreadPool(2); 
eService.execute(new TestThread6()); 
eService.execute(new TestThread6()); 
eService.execute(new TestThread6()); 
eService.awaitTermination(1, TimeUnit.NANOSECONDS); 
eService.shutdown(); 

eService.shutdown(); 
eService.awaitTermination(1, TimeUnit.NANOSECONDS); 

Tôi không thực sự hiểu shutdown() là gì. Phương thức này không chờ đợi các tác vụ được gửi trước đó để hoàn thành việc thực hiện. Có nghĩa là shutdown() có thể chấm dứt các tác vụ đã được gửi, nhưng chưa hoàn thành? Tôi đã thử một số ví dụ, họ không chứng minh điều đó, xin vui lòng cho tôi một ví dụ.

+0

Hãy xem: https://stackoverflow.com/questions/36644043/how-to-properly-shutdown-java-executorservice/36644320#36644320 –

Trả lời

25

Trước tiên, bạn nên gọi số shutdown. Nếu không, bạn có thể chờ đợi một thời gian rất dài, vì awaitTermination không thực sự tắt máy thực thi của bạn.

Nếu bạn muốn đợi các tác vụ hoàn tất, thay vì đợi cho người thực hiện tắt, thì bạn nên sử dụng invokeAll.

+0

cảm ơn, nhưng tại sao chờ đợi một thời gian rất dài? bạn có thể cho tôi một số ví dụ để giải thích? –

+0

@ user2245634 'awaitTermination' không thực sự tắt trình xử lý của bạn trước. Vì vậy, trừ khi một luồng khác tắt trình xử lý, 'awaitTermination' sẽ chỉ ngồi đó cho đến khi hết thời gian chờ. Rõ ràng, trong ví dụ của bạn, bạn đã chờ đợi chỉ 1 nano giây trước khi hết thời gian, đó là lý do tại sao bạn không quan sát "thời gian rất dài". –

+0

cảm ơn, tôi hiểu, và trong shutdown() api: Phương pháp này không chờ đợi cho các nhiệm vụ được gửi trước đó để hoàn thành thực hiện. nó có nghĩa là có thể tắt() có thể chấm dứt nhiệm vụ đã nộp, nhưng không hoàn thành? nhưng tôi thử một số ví dụ không chứng minh nó –

1

Sau khi chúng tôi bắt đầu tác vụ đầu tiên ThreadPoolExecutor sẽ bắt đầu một chuỗi sẽ không kết thúc ngay cả sau khi tác vụ được hoàn tất. Ít nhất nó là đúng cho một hồ bơi cố định thread. Đây là lý do tại sao chúng ta cần phải gọi tắt máy. Sau khi tắt ThreadPoolExecutor sẽ từ chối bất kỳ nhiệm vụ mới nhưng sẽ chờ đợi cho các nhiệm vụ đang chạy để kết thúc và sau đó cho phép các Threads kết thúc. Đây là lý do tại sao chúng tôi cần awaitTermination sau khi shutdwon.

13

shutdown nghĩa là dịch vụ thực thi không còn tác vụ đến nào nữa.

awaitTermination được gọi sau khi yêu cầu tắt máy.

Trước tiên, bạn cần phải tắt dịch vụ và sau đó chặn và chờ chủ đề kết thúc.

Nếu bạn muốn xem tất cả các chủ đề kết thúc chạy và nhấn mạnh vào việc sử dụng awaiTermination, bạn cần đặt thông số hết thời gian chờ đủ lớn. Vì vậy, bạn có thể làm:

eService.shutdown(); 
if (!eService.awaitTermination(60000, TimeUnit.SECONDS)) 
    System.err.println("Threads didn't finish in 60000 seconds!"); 
} 

Ngoài ra, bạn có thể làm:

eService.shutdown(); 
while (!eService.isTerminated()) { 

} 

Bằng cách này bạn có thể để đảm bảo tất cả các chủ đề đã kết thúc chạy, trừ khi họ bị gián đoạn bất ngờ.

+2

có thể là mili giây ... 60000s là 16.666 giờ. –

+11

Đừng bận chờ đợi như đoạn mã thứ hai. Chỉ. Đừng. – Alexander

27

Đọc tài liệu hướng dẫn luôn giúp:

shutdownNow:

nỗ lực để ngăn chặn tất cả các nhiệm vụ chủ động thực hiện, tạm dừng việc xử lý của nhiệm vụ chờ đợi, và trả về một danh sách các nhiệm vụ đã được chờ đợi thực thi. Các tác vụ này được rút ra (bị xóa) khỏi hàng đợi nhiệm vụ khi trở về từ phương thức này.

Phương thức này không chờ đợi cho các tác vụ thực thi tích cực chấm dứt. Sử dụng awaitĐiều chỉnh để thực hiện điều đó.

Không có đảm bảo nào ngoài nỗ lực hết sức nỗ lực để ngừng xử lý chủ động thực hiện các tác vụ. Triển khai này hủy nhiệm vụ qua Chủ đề.gián đoạn(), vì vậy bất kỳ nhiệm vụ nào không đáp ứng với ngắt có thể không bao giờ chấm dứt

shutdown:

Ðồng một trật tự tắt máy, trong đó nhiệm vụ đệ trình trước đây là thực hiện, nhưng không mới nhiệm vụ sẽ được chấp nhận. Yêu cầu không có hiệu ứng bổ sung nếu đã tắt.

Phương pháp này không chờ cho các tác vụ được gửi trước đây để hoàn thành việc thực thi . Sử dụng awaitTermination để làm điều đó.

awaitTermination:

Blocks cho đến khi tất cả các nhiệm vụ đã hoàn thành thi công sau khi một yêu cầu tắt máy, hoặc thời gian chờ xảy ra, hoặc các chủ đề hiện hành bị gián đoạn, nào đến trước.

+0

Tôi không hiểu tài liệu để tắt máy. Đầu tiên nó nói "các nhiệm vụ được gửi trước đó được thực hiện" và sau đó nó nói "phương pháp này không chờ đợi các nhiệm vụ được gửi trước đó để hoàn thành việc thực hiện." Vậy, nhiệm vụ của tôi có hoàn thành hay không? – jrahhali

+5

@jrahhali Nó có nghĩa là trả về cuộc gọi phương thức ngay lập tức. I E. chủ đề gọi là 'shutdown' không chặn. –

+0

Ahh, không chặn. Điều đó có ý nghĩa bây giờ. Họ nên sử dụng từ đó thay vì chờ đợi. Cảm ơn. – jrahhali

0

Bạn cần gọi phương thức shutdownNow() sau khi cuộc gọi phương thức awaitTermination() đã xảy ra. Sau đó, chỉ bạn mới có thể tìm hiểu cách sử dụng thực tế của phương thức awaitTermination()

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