11

Về cơ bản, tiêu đề câu hỏi nói gì.Không gọi Thread.interrupt() trước một Thread.join() gây ra tham gia() để ném một InterruptedException ngay lập tức?

Thread t = new Thread(someRunnable); 
t.start(); 
t.interrupt(); 
t.join(); //does an InterruptedException get thrown immediately here? 

Từ các thử nghiệm của riêng tôi, có vẻ như, nhưng chỉ muốn chắc chắn. Tôi đoán Thread.join() kiểm tra trạng thái interrupted của luồng trước khi thực hiện "chờ" thường trình của nó?

+2

Không, Thread.join() chỉ liên quan đến gián đoạn đến chuỗi * hiện tại *. – EJP

Trả lời

14

interrupt() ngắt chuỗi bạn bị gián đoạn, không phải chuỗi đang làm gián đoạn.

c.f.

Thread.currentThread().interrupt(); 
t.join(); // will throw InterruptedException 
14

Liệu gọi Thread.interrupt() trước khi một Thread.Join() gây join() để ném một InterruptedException ngay lập tức?

Không nó sẽ không ném. Chỉ khi chủ đề hiện tại đang gọi phương thức join() bị gián đoạn sẽ join() ném InterruptedException. t.interrupt() đang làm gián đoạn chuỗi bạn vừa mới bắt đầu, trong khi t.join() sẽ chỉ ném InterruptedException nếu chuỗi đang thực hiện thao tác nối (có thể là chuỗi chính?) Bị gián đoạn.

Thread t = new Thread(someRunnable); 
t.start(); 
t.interrupt(); 
t.join(); // will _not_ throw unless this thread calling join gets interrupted 

Ngoài ra nó quan trọng là phải nhận ra rằng làm gián đoạn một sợi không hủy nó join() không giống như một Future ở chỗ nó sẽ trở lại với ngoại lệ thread ném.

Khi bạn làm gián đoạn một chuỗi, bất kỳ cuộc gọi nào mà chuỗi đang thực hiện đến sleep(), wait(), join() và các phương pháp gián đoạn khác sẽ ném InterruptedException. Nếu những phương thức đó không được gọi thì luồng sẽ tiếp tục chạy. Nếu chuỗi làm ném một số InterruptedException để phản hồi bị gián đoạn và sau đó thoát, ngoại lệ đó sẽ bị mất trừ khi bạn đã sử dụng t.setDefaultUncaughtExceptionHandler(handler).

Trong trường hợp của bạn, nếu chuỗi bị gián đoạn và kết thúc bởi vì nó trả về, sau đó tham gia sẽ kết thúc - nó sẽ không ném một ngoại lệ. Mã chuỗi phổ biến để xử lý ngắt đúng cách như sau:

public void run() { 
    try { 
     Thread.sleep(10000); 
    } catch (InterruptedException e) { 
     // a good pattern is to re-interrupt the thread when you catch 
     Thread.currentThread().interrupt(); 
     // another good pattern is to make sure that if you _are_ interrupted, 
     // that you stop the thread 
     return; 
    } 
}