Java Concurrency - Chính sách về Gián đoạn
Tôi đang đọc Java Concurrency trên thực tế . Trong phần Chính sách gián đoạn trong chương
Hủy và tắt máy
Nó được đề cập
Một tác vụ không được giả định bất cứ điều gì về chính sách gián đoạn của chuỗi thực thi của nó trừ khi nó được thiết kế rõ ràng để chạy trong một dịch vụ có chính sách gián đoạn cụ thể. Cho dù một tác vụ diễn giải gián đoạn là hủy bỏ hoặc thực hiện một số hành động khác đối với sự gián đoạn, thì nó cần lưu ý để duy trì trạng thái gián đoạn của chuỗi đang thực thi. Nếu nó không truyền InterruptException đến người gọi của nó, nó sẽ khôi phục trạng thái ngắt sau khi bắt InterruptException: Thread.currentThread (). Ngắt ()
Vì vậy, tôi đã cố gắng thử với mẫu danh sách để hiểu. Nhưng tôi đang bối rối với đầu ra.
Thủ tướng Chính phủ
public class CorrectPrimeProducer extends Thread {
private final BlockingQueue<BigInteger> queue;
public CorrectPrimeProducer(BlockingQueue<BigInteger> queue) {
this.queue = queue;
}
@Override
public void run() {
try {
System.out.println(Thread.currentThread().getName()+" interrupt status in producer:" + Thread.currentThread().isInterrupted());
BigInteger p = BigInteger.ONE;
while (!Thread.currentThread().isInterrupted()) {
queue.put(p = p.nextProbablePrime());
}
} catch (InterruptedException e) {
/* Allow thread to exit */
Thread.currentThread().interrupt();
System.out.println(Thread.currentThread().getName()+" interrupt status in producer catch:" + Thread.currentThread().isInterrupted());
}
}
}
phương thức chính ##
public static void main(String[] args) throws InterruptedException {
BlockingQueue<BigInteger> primes = new LinkedBlockingQueue<>();
CorrectPrimeProducer generator = new CorrectPrimeProducer(primes);
generator.start();
try {
while (needMorePrimes()) {
consume(primes.take());
}
} finally {
generator.interrupt();
}
TimeUnit.SECONDS.sleep(5);
System.out.println(generator.getName()+" interrupt status in main:"+generator.isInterrupted());
}
//do something
private static void consume(BigInteger take) {
System.out.println(take);
}
private static int counter = 1;
private static boolean needMorePrimes() {
counter++;
if(counter == 10){
// after counter reaches 10 return false
return false;
}
return true;
}
Đầu ra:
// when TimeUnit.SECONDS.sleep(5); in main class is not commented
Thread-0 interrupt status in producer:false
2
3
5
7
11
13
17
19
Thread-0 interrupt status in producer catch:true
Thread-0 interrupt status in main:false
//When TimeUnit.SECONDS.sleep(5); in main class is commented
Thread-0 interrupt status in producer:false
2
3
5
7
11
13
17
19
Thread-0 interrupt status in main:true
Thread-0 interrupt status in producer catch:true
Câu hỏi
Chỉ cần thêm TimeUnit.SECONDS.sleep (5) trong luồng chính trong lớp chính. Trạng thái ngắt luồng đang thực thi (tức là trình tạo) đang được đặt lại. Nếu tôi nhận xét phương thức TimeUnit.SECONDS.sleep (5) thì trong trường hợp đó trạng thái ngắt được giữ lại. Tại sao điều này xảy ra và làm thế nào?
Trong cuốn sách, nó đã đề cập Một chuỗi chỉ nên bị gián đoạn bởi chủ nhân của nó. Ở đây trong ví dụ trên ai là chủ sở hữu? Tôi nghĩ rằng chủ đề phương pháp chính của nó.
Trả lời
Bằng cách thêm TimeUnit.SECONDS.sleep(5)bạn đang cho đủ thời gian để chuỗi kết thúc.
Khi một luồng kết thúc, cờ ngắt của nó sẽ bị xóa.
Điều này không được ghi lại trong thông số kỹ thuật, nhưng đó là những gì sẽ xảy ra. Xem ví dụ báo cáo lỗi này :
Không có thông số kỹ thuật nào bị vi phạm ở đây vì vậy tôi đã thực hiện đây là một yêu cầu nâng cao chứ không phải là một lỗi. Có thể cho rằng việc thiếu đặc điểm kỹ thuật là một lỗi - chúng tôi đã cố ý chỉ định rằng "ngắt sau khi kết thúc cần không ảnh hưởng" để giải quyết thực tế là trạng thái ngắt được lưu trữ trong máy ảo và không còn tồn tại khi một luồng đã kết thúc. Tuy nhiên, chúng tôi đã sơ ý phản ánh điều đó trong thông số Thread.isInterrupt.
Nếu không có phần bổ sung sleep, tôi nghi ngờ rằng về lý thuyết, bạn có thể thấy cả hai trạng thái gián đoạn truevà falsetrạng thái gián đoạn bởi vì có một điều kiện cuộc đua, nhưng có nhiều khả năng bạn sẽ thấy truenhờ lập lịch luồng. Cửa sổ thời gian mà trạng thái ngắt là false, giữa ngoại lệ được ném ra và trạng thái ngắt được khôi phục trong khối bắt, là cực kỳ nhỏ.
Chỉ cần thêm TimeUnit.SECONDS.sleep (5) trong luồng chính trong lớp chính. Trạng thái ngắt luồng đang thực thi (tức là trình tạo) đang được đặt lại. Nếu tôi nhận xét phương thức TimeUnit.SECONDS.sleep (5) thì trong trường hợp đó trạng thái ngắt được giữ lại. Tại sao điều này xảy ra và làm thế nào?
Bạn không sử dụng bất kỳ cơ chế đồng bộ hóa nào (ngoài hàng đợi chặn) giữa luồng chính và CorrectPrimeProducerkhi luồng chính in trạng thái - CorrectPrimeProducercó thể chưa duy trì trạng thái bị gián đoạn (bằng cách thực hiện các catchlệnh khối), do đó bạn nhận được falsekết quả như vậy.
Khi bạn thêm sleepvào luồng chính, Threadbạn chỉ tăng khả năng CorrectPrimeProducerluồng duy trì trạng thái gián đoạn bằng cách gọi các catchlệnh khối trước khi luồng chính cố gắng in trạng thái của nó. Đó là lý do tại sao nó in true.
Trong cuốn sách, nó đã đề cập Một chuỗi chỉ nên bị gián đoạn bởi chủ nhân của nó. Ở đây trong ví dụ trên ai là chủ sở hữu? Tôi nghĩ rằng chủ đề phương pháp chính của nó.
Trong trường hợp này, bạn là chủ sở hữu (chủ sở hữu là mã tạo ra chuỗi) của CorrectPrimeProducerchuỗi, vì vậy bạn quyết định gián đoạn có ý nghĩa như thế nào đối với nó. Ví dụ: bạn có thể tạo lại nó nếu nó bị gián đoạn (điều này xảy ra, ví dụ: đối với Threads từ các nhóm luồng java theo mặc định).