2009-12-13 60 views
11

Trong Effective Java (trang 275), có đoạn mã này:Tại sao bạn lại bắt được InterruptedException để gọi Thread.currentThread.interrupt()?

... 
for (int i = 0; i < concurrency; i++) { 
    executor.execute(new Runnable() { 
    public void run() { 
    ready.countDown(); 
    try { 
     start.await(); 
     action.run(); 
    } catch (InterruptedException e) { 
     Thread.currentThread().interrupt(); 
    } finally { 
     done.countDown(); 
    } 
    } 
} 
... 

việc sử dụng bắt ngoại lệ bị gián đoạn chỉ để lại nuôi nó là gì? Tại sao không chỉ để nó bay?

Trả lời

15

Câu trả lời đơn giản là InterruptedException là ngoại lệ được kiểm tra và không nằm trong chữ ký của phương thức Runnable.run (hoặc phương pháp Executable.execute()). Vì vậy, bạn phải nắm bắt nó. Và một khi bạn đã bắt được nó, hãy gọi Thread.interrupt() để đặt cờ bị gián đoạn là điều được khuyến nghị thực hiện ... trừ khi bạn thực sự có ý định đè bẹp ngắt.

+1

Giả sử bạn muốn chuỗi thực sự bị gián đoạn. Bạn chỉ có thể nắm bắt và nuốt các trường hợp ngoại lệ cũng sẽ ngăn chặn sự gián đoạn thread. –

+0

Bạn có nghĩa là nó không có trong chữ ký của Runnable. Thay vào đó, tôi sẽ sử dụng một cuộc gọi. Ngoài ra - gọi Thread.currentThread(). Interrupt() sẽ không ném ngoại lệ đó? Vì vậy, những gì là điểm trong ném nó? – ripper234

+0

Tôi tin rằng bạn có nghĩa là 'InterruptedException' là một ngoại lệ được kiểm tra và không có chữ ký của' Runnable.run() '(không phải' Executor.execute'). – Tom

0

Đôi khi bạn không thể bỏ qua ngoại lệ và bạn phải bắt nó. Chủ yếu điều này xảy ra khi bạn ghi đè phương thức không thể ném InterruptedException theo chữ ký của nó. Ví dụ, phương pháp này thường được sử dụng trong phương pháp Runnable.run().

0

Người thực thi có thể làm gián đoạn công việc nếu chúng bị hủy nhưng nó xóa cờ bị gián đoạn giữa các tác vụ để tránh một tác vụ bị hủy làm gián đoạn công việc không liên quan.

Như vậy, việc ngắt chuỗi hiện tại ở đây sẽ rất nguy hiểm nếu nó thực sự làm bất cứ điều gì.

Cách đơn giản hơn xung quanh việc này là sử dụng Có thể gọi hoặc bỏ qua ngắt. Ngoài ra nó là một ý tưởng tốt để nắm bắt và đăng nhập bất kỳ lỗi hoặc ngoại lệ ném trong khối try/catch nếu không ngoại lệ/lỗi sẽ được loại bỏ và chương trình của bạn có thể thất bại nhưng bạn sẽ không biết nó là hoặc tại sao.

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