Khi nào thì Thread.sleep của Java ném ra InterruptException?


110

Khi nào thì Thread.sleep của Java ném ra InterruptException? Bỏ qua nó có an toàn không? Tôi không thực hiện bất kỳ đa luồng nào. Tôi chỉ muốn đợi vài giây trước khi thử lại một số thao tác.



1
Phụ thuộc vào ý nghĩa của bạn là "bỏ qua". InterruptedExceptionlà một ngoại lệ bị bắt, vì vậy bạn không thể biên dịch trừ khi bạn xử lý hoặc khai báo loại ngoại lệ này trên bất kỳ phương thức nào tham gia hoặc ngủ a Thread, hoặc gọi wait()trên Object.
8bitjunkie

Câu trả lời:


41

Nói chung, bạn KHÔNG nên bỏ qua ngoại lệ. Hãy xem bài báo sau:

Đừng ngắt lời

Đôi khi việc ném InterruptException không phải là một tùy chọn, chẳng hạn như khi một tác vụ được xác định bởi Runnable gọi một phương thức có thể ngắt. Trong trường hợp này, bạn không thể kích hoạt lại InterruptException, nhưng bạn cũng không muốn làm gì cả. Khi một phương thức chặn phát hiện ra sự gián đoạn và ném InterruptException, nó sẽ xóa trạng thái bị gián đoạn. Nếu bạn bắt được InterruptException nhưng không thể ném lại nó, bạn nên lưu giữ bằng chứng rằng sự gián đoạn đã xảy ra để mã cao hơn trên ngăn xếp cuộc gọi có thể tìm hiểu về sự gián đoạn và phản hồi nó nếu nó muốn. Tác vụ này được thực hiện bằng cách gọi hàm ngắt () để "ngắt kết nối" luồng hiện tại, như được hiển thị trong Liệt kê 3. Ít nhất, bất cứ khi nào bạn bắt được InterruptException và không ném lại nó, hãy ngắt luồng hiện tại trước khi quay lại.

public class TaskRunner implements Runnable {
    private BlockingQueue<Task> queue;

    public TaskRunner(BlockingQueue<Task> queue) { 
        this.queue = queue; 
    }

    public void run() { 
        try {
             while (true) {
                 Task task = queue.take(10, TimeUnit.SECONDS);
                 task.execute();
             }
         }
         catch (InterruptedException e) { 
             // Restore the interrupted status
             Thread.currentThread().interrupt();
         }
    }
}

Xem toàn bộ bài báo tại đây:

http://www.ibm.com/developerworks/java/library/j-jtp05236/index.html?ca=drs-


38

Nếu một InterruptedExceptionđược ném, nó có nghĩa là một cái gì đó muốn làm gián đoạn (thường kết thúc) luồng đó. Điều này được kích hoạt bởi một cuộc gọi đến interrupt()phương thức luồng . Phương thức chờ phát hiện điều đó và ném InterruptedExceptionmã bắt để có thể xử lý yêu cầu chấm dứt ngay lập tức và không phải đợi cho đến khi hết thời gian quy định.

Nếu bạn sử dụng nó trong một ứng dụng đơn luồng (và cả trong một số ứng dụng đa luồng), ngoại lệ đó sẽ không bao giờ được kích hoạt. Bỏ qua nó bằng cách có một điều khoản bắt trống mà tôi không khuyên bạn nên làm. Việc ném nó InterruptedExceptionsẽ xóa trạng thái bị gián đoạn của chuỗi, vì vậy nếu không được xử lý đúng cách, thông tin đó sẽ bị mất. Do đó, tôi đề xuất chạy:

} catch (InterruptedException e) {
  Thread.currentThread().interrupt();
  // code for stopping current task so thread stops
}

Mà thiết lập lại trạng thái đó. Sau đó, kết thúc thực hiện. Đây sẽ là hành vi đúng đắn, thậm chí không bao giờ được sử dụng.

Điều gì có thể tốt hơn là thêm điều này:

} catch (InterruptedException e) {
  throw new RuntimeException("Unexpected interrupt", e);
}

... câu lệnh cho khối bắt. Về cơ bản, điều đó có nghĩa là nó không bao giờ được xảy ra. Vì vậy, nếu mã được sử dụng lại trong một môi trường mà nó có thể xảy ra, nó sẽ phàn nàn về nó.


5
Các xác định trong Java bị tắt theo mặc định . Vì vậy, tốt hơn là chỉ cần ném một RuntimeException.
Evgeni Sergeev


5

Các phương thức như sleep()wait()của lớp Threadcó thể ném một InterruptedException. Điều này sẽ xảy ra nếu một số người khác threadmuốn làm gián đoạn những threadgì đang chờ hoặc ngủ.


3

Một cách chắc chắn và dễ dàng để xử lý nó trong mã luồng đơn là bắt nó và khôi phục nó trong RuntimeException, để tránh phải khai báo nó cho mọi phương thức.


-7

Các InterruptedExceptionthường được ném khi một giấc ngủ bị gián đoạn.


13
Điều đó sai, vì bản thân giấc ngủ không được xen vào, mà là Luồng đang chạy nó. Bị gián đoạn là một trạng thái Chủ đề. Nó chỉ dẫn đến phương pháp ngủ bị thoát ra.
ubuntudroid
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.