Câu trả lời:
Điều này được thực hiện để giữ cho nhà nước .
Khi bạn bắt InterruptException
và nuốt nó, về cơ bản, bạn sẽ ngăn không cho bất kỳ phương thức / nhóm luồng cấp cao nào chú ý đến ngắt. Mà có thể gây ra vấn đề.
Bằng cách gọi Thread.currentThread().interrupt()
, bạn đặt cờ ngắt của luồng, vì vậy trình xử lý ngắt cấp cao hơn sẽ nhận thấy nó và có thể xử lý nó một cách thích hợp.
Thực hành đồng thời Java thảo luận điều này chi tiết hơn trong Chương 7.1.3: Ứng phó với sự gián đoạn . Quy tắc của nó là:
Chỉ mã thực hiện chính sách gián đoạn của một luồng có thể nuốt một yêu cầu gián đoạn. Nhiệm vụ mục đích chung và mã thư viện không bao giờ nên nuốt các yêu cầu gián đoạn.
interrupt()
cuộc gọi là cách duy nhất để đặt cờ bị gián đoạn khi bạn nhận được thông báo về trạng thái này thông qua "cơ chế phân phối" khác - InterruptedException
và muốn hoặc không thể ném lại.
Tôi nghĩ rằng mẫu mã này làm cho mọi thứ một chút rõ ràng. Lớp học thực hiện công việc:
public class InterruptedSleepingThread extends Thread {
@Override
public void run() {
doAPseudoHeavyWeightJob();
}
private void doAPseudoHeavyWeightJob() {
for (int i=0;i<Integer.MAX_VALUE;i++) {
//You are kidding me
System.out.println(i + " " + i*2);
//Let me sleep <evil grin>
if(Thread.currentThread().isInterrupted()) {
System.out.println("Thread interrupted\n Exiting...");
break;
}else {
sleepBabySleep();
}
}
}
/**
*
*/
protected void sleepBabySleep() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
//e.printStackTrace();
Thread.currentThread().interrupt();
}
}
}
Lớp chính:
public class InterruptedSleepingThreadMain {
/**
* @param args
* @throws InterruptedException
*/
public static void main(String[] args) throws InterruptedException {
InterruptedSleepingThread thread = new InterruptedSleepingThread();
thread.start();
//Giving 10 seconds to finish the job.
Thread.sleep(10000);
//Let me interrupt
thread.interrupt();
}
}
Hãy thử ngắt cuộc gọi mà không đặt lại trạng thái.
Ghi chú:
http://doad.oracle.com/javase/7/docs/technotes/guides/concurrency/threadPrimitiveDeprecation.html
Làm cách nào để dừng một chuỗi chờ trong thời gian dài (ví dụ: cho đầu vào)?
Để kỹ thuật này hoạt động, điều quan trọng là bất kỳ phương pháp nào bắt được ngoại lệ ngắt và không được chuẩn bị để xử lý ngay lập tức sẽ xác nhận lại ngoại lệ đó. Chúng tôi nói rằng tái khẳng định hơn là rút lại, bởi vì không phải lúc nào cũng có thể lấy lại ngoại lệ. Nếu phương thức bắt InterruptedException không được khai báo để ném ngoại lệ (đã kiểm tra) này, thì nó sẽ "tự gián đoạn lại" với câu thần chú sau:
Thread.currentThread().interrupt();
Điều này đảm bảo rằng Thread sẽ phục hồi InterruptedException ngay khi có thể.
Tôi sẽ coi đó là một thực hành xấu hoặc ít nhất là một chút rủi ro. Thông thường các phương thức cấp cao hơn không thực hiện các hoạt động chặn và chúng sẽ không bao giờ nhìn thấyInterruptedException
ở đó. Nếu bạn che giấu nó ở mọi nơi bạn thực hiện thao tác gián đoạn, bạn sẽ không bao giờ có được nó.
Lý do duy nhất cho Thread.currentThread.interrupt()
và không đưa ra bất kỳ ngoại lệ hoặc yêu cầu ngắt tín hiệu nào theo bất kỳ cách nào khác (ví dụ: đặt interrupted
biến biến cục bộ trong vòng lặp chính của luồng) là tình huống mà bạn thực sự không thể làm gì với ngoại lệ, như trong các finally
khối.
Xem câu trả lời của Péter Török, nếu bạn muốn hiểu rõ hơn về hàm ý của Thread.currentThread.interrupt()
cuộc gọi.
Tham khảo từ tài liệu java
Nếu chuỗi này bị chặn trong một lệnh gọi Wait (), tham gia (), ngủ (dài), thì trạng thái ngắt của nó sẽ bị xóa và nó sẽ nhận được InterruptedException.
Nếu luồng này bị chặn trong thao tác I / O, trạng thái ngắt của luồng sẽ được đặt và luồng sẽ nhận được một ĐóngByInterruptException.
Nếu luồng này bị chặn trong Bộ chọn thì trạng thái ngắt của luồng sẽ được đặt và nó sẽ trở lại ngay lập tức từ thao tác chọn.
Nếu không có điều kiện nào trước đó giữ thì trạng thái ngắt của luồng này sẽ được đặt.
Vì vậy, nếu bạn thay đổi phương thức ngủBabyS ngủ () trong @Ajay George Trả lời thao tác I / O hoặc chỉ một sysout, bạn không phải đặt lại trạng thái để dừng chương trình. (BTW, họ thậm chí không ném Interrupttedception)
Giống như @ Péter Török đã nói => Điều này được thực hiện để giữ trạng thái. (Và đặc biệt đối với phương thức sẽ ném Interrupttedception)
InterruptedException
trạng thái ngắt rõ ràng khi thực hiện. Tôi nghĩ rằng điều này làm cho câu trả lời rõ ràng hơn về lý do tại sao bạn cần duy trì trạng thái ngắt.