2013-04-08 47 views
6

Đây là một câu hỏi về Java cũ khi chúng tôi tạo ra các Chủ đề của riêng mình. Một số phương pháp như Thread.sleep(100) ném một số InterruptedException khi nó bị gián đoạn bởi một chuỗi khác. Bây giờ như tôi hiểu, gián đoạn có nghĩa là một sợi dây khác đang nói: Hãy để tôi tiếp quản ngay bây giờ.Tại sao InterruptedException là ngoại lệ được kiểm tra?

Khi điều này xảy ra, tại sao Java muốn chúng tôi xử lý InterruptedException?

Lập trình viên thậm chí không cần quan tâm khi các chuỗi đang làm gián đoạn lẫn nhau. Anh ta nên chỉ có thể phân chia công việc giữa các chủ đề và được chú ý khi nó được thực hiện. Vì vậy, lý do của Java muốn chúng ta đối phó với InteruptedException là gì? Ít nhất nó phải được RuntimeException

+0

Tôi đoán đây là để nhà phát triển thực hiện hành động thích hợp bất cứ khi nào chuỗi bị gián đoạn. Chủ đề có thể đang thực hiện một số tác vụ quan trọng và có thể cần phải xử lý gián đoạn theo cách chính xác. –

+0

Để buộc bạn bắt nó. – EJP

+2

Vui lòng không đóng. Có một số câu trả lời tuyệt vời ở đây – Victor

Trả lời

6

Lập trình viên thậm chí không cần phải quan tâm khi các sợi dây được làm gián đoạn mỗi khác

Điều này không đúng. Có rất nhiều, nhiều tình huống mà bạn muốn biết rằng một sự gián đoạn đã được yêu cầu, nhưng bạn sẽ bỏ qua nó một chút để hoàn thành công việc bạn đang làm.

Ví dụ: giả sử một chuỗi mở một tệp và bắt đầu viết một số dữ liệu. Chủ đề này, sau đó, khối, chờ đợi cho phần còn lại của dữ liệu được tính toán. Giả sử rằng một luồng thứ hai cố gắng làm gián đoạn luồng thứ nhất. Nó nên làm gì? Đơn giản chỉ cần chết, và có thể bạn kết thúc với một tập tin bị hỏng, không đầy đủ? Nó có nên dọn dẹp bằng cách xóa tập tin mà nó bắt đầu viết không? Có nên bỏ qua yêu cầu gián đoạn và chỉ cần đợi cho đến cuối dữ liệu cần ghi? Nó có nên viết một cái gì đó có nghĩa là "Tôi đã bị gián đoạn ở đây", để nó có thể tiếp tục công việc của nó từ thời điểm đó trong thời gian tới?

Trên một trường hợp khác, giả sử bạn có máy chủ HTTP. Giả sử người dùng đang truy cập vào máy chủ của bạn và, tải xuống một tệp lớn từ máy chủ của bạn. Bạn muốn dừng máy chủ. Ứng dụng sau đó sẽ cố gắng làm gián đoạn tất cả các chuỗi công việc. Họ nên làm gì? Chỉ cần dừng tải xuống? Hoặc họ có nên đợi người dùng tải xuống các tệp của họ và chỉ sau đó họ có nên chết mà không chấp nhận thêm bất kỳ yêu cầu nào nữa không? Cả hai kịch bản đều có giá trị như nhau.

Như bạn thấy, có quá nhiều kịch bản có thể xảy ra và sẽ thật khủng khiếp nếu chúng tôi không có cách nào để biết rằng một sự gián đoạn đã được yêu cầu. Đôi khi, bạn sẽ chỉ đơn giản là để cho thread chết. Đôi khi, bạn phải làm sạch môi trường. Đôi khi, bạn muốn nó hoàn thành yêu cầu đang hoạt động nhưng không chấp nhận thêm bất kỳ yêu cầu nào.

+2

Không chắc chắn cách này trả lời câu hỏi - mọi thứ bạn đã viết ở trên sẽ dễ dàng đạt được nếu InterruptedException không được chọn. – Peter

+0

@Peter Thực tế là nó được kiểm tra yêu cầu người sử dụng API của bạn mà có thể ném ngoại lệ để đối phó một cách rõ ràng với nó bằng cách nào đó. Nếu nó đã được bỏ chọn và không bị bắt, nó sẽ chỉ ném ngoại lệ và có thể chấm dứt chương trình có nghĩa là tất cả các trường hợp trên của các tập tin bị hỏng và kết nối bị gián đoạn là có thể. Làm cho nó được kiểm tra là một cách để đảm bảo người dùng chắc chắn không bỏ lỡ phần quan trọng trong việc xử lý ngoại lệ. –

3

Có vẻ như bạn đang trộn giữa trình lên lịch chủ đề và gián đoạn.

Trình lên lịch chuỗi là một hệ thống gốc, phân chia công việc từ nhiều luồng thành các quy trình. Nếu quá nhiều luồng đang hoạt động, trình lên lịch sẽ hoạt động không đồng bộ. Nói cách khác, hãy để tôi tiếp quản bây giờ có thể khá đúng.

Một phương tiện gián đoạn, thoát khỏi những gì bạn hiện đang làm và không quay lại với số. Cách thực tế nhất để thực hiện điều này, là một ngoại lệ.

+0

Theo Oracle, http://docs.oracle.com/javase/tutorial/essential/concurrency/interrupt.html, * "Một phương tiện gián đoạn, thoát khỏi những gì bạn hiện đang làm và ** không quay trở lại với nó * * "*, không hoàn toàn chính xác. Nó nói: "Một ngắt là một dấu hiệu cho thấy một chuỗi mà nó sẽ dừng lại những gì nó đang làm và làm một cái gì đó khác. ** Đó là lập trình viên để quyết định chính xác cách một sợi phản ứng với một ngắt **". không có hành vi tiêu chuẩn như "không quay trở lại với nó". Một ngắt chỉ là một cách của một luồng tín hiệu một cái gì đó đến một chủ đề khác, và điều này có thể được thực hiện để có nghĩa là "bỏ" hoặc không –

0

An InteruptedException được ném khi một luồng bị buộc phải bị gián đoạn. Đây không phải là tình huống thông thường (tức là khi luồng được bật lên bởi trình lên lịch). Ví dụ sẽ là khi một luồng khác manually interupts it hoặc quá trình nhận được tín hiệu SIGINT .

+0

SIGKILL sẽ không làm gián đoạn chủ đề; nó trực tiếp giết chết chúng, nó giết chết toàn bộ quá trình JVM. –

+0

Xin lỗi, xấu của tôi, ý tôi là 'SIGINT'. – SimonC

+0

SIGINT sẽ không gọi '.interrupt()' trên luồng. Nó sẽ chỉ có thể chạy bất kỳ móc tắt máy nào mà bạn đã thêm vào. Nếu nó đã làm gián đoạn các luồng, nó có thể gây ra sự tàn phá: bạn có thể cần phải chấm dứt các luồng của bạn theo một thứ tự rất cụ thể, JVM sẽ biết đúng thứ tự như thế nào? –

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