java - sleep 时线程中断

标签 java multithreading

在下面的示例中,我尝试正常终止两个线程。消费者线程在 sleep 时被中断,这应该将 isInterrupted 标志设置为 true。然而,对 while 循环的 !Thread.currentThread().isInterrupted() 检查似乎仍然返回 = false,因为它不会终止使用者线程。

将以下代码复制并粘贴到 IDE 中进行检查:

public class ThreadInterruptExample {

public static void main(String[] args) throws InterruptedException {
    LinkedBlockingQueue<String> queue = new LinkedBlockingQueue<String>(1);
    ThreadInterruptExample ie = new ThreadInterruptExample();
    Producer producer = ie.new Producer(queue);
    Consumer consumer = ie.new Consumer(queue, producer);
    producer.start();
    consumer.start();
    Thread.sleep(1000);
    producer.cancel();
    consumer.cancel();
}

class BaseQueue extends Thread {
    protected final BlockingQueue<String> queue;

    public BaseQueue(BlockingQueue<String> queue) {
        this.queue = queue;
    }

    public void cancel() {
        System.out.println(this.getName() + " - Shutting down");
        interrupt();
    }
}

class Producer extends BaseQueue {
    private final List<String> messages = Arrays.asList("a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q",
            "r", "s", "t", "u", "v", "w", "x", "y", "z");

    public Producer(BlockingQueue<String> queue) {
        super(queue);
        this.setName("Producer");
    }

    public void run() {
        try {
            for (String message : messages) {
                System.out.println(this.getName() + ": Sending " + message);
                queue.put(message);
            }
        } catch (InterruptedException e) {
            System.out.println(this.getName() + " - InterruptedException occurred");
        }
    }
}

class Consumer extends BaseQueue {
    private final BaseQueue producer;

    public Consumer(BlockingQueue<String> queue, BaseQueue producerQueue) {
        super(queue);
        this.setName("Consumer");
        producer = producerQueue;
    }

    @Override
    public void run() {
        while (!Thread.currentThread().isInterrupted()) {
            System.out.println(this.getName() +": Consumer Running");
            String message = "";
            try {
                Thread.sleep(1500);
                message = queue.take();
                System.out.println(this.getName() + ": Recevied " + message);
                if (message.equals("pill")) {
                    producer.cancel();
                    this.cancel();
                }
            } catch (InterruptedException e) {
                System.out.print(this.getName() + ": Exception occurred for: " + message);
                e.printStackTrace();
            }
        }
    }

}

}

最佳答案

当您捕获 InterruptedException 时,您将丢弃中断。有两种解决方案。

while (!Thread.currentThread().isInterrupted()) {
    try {
        Thread.sleep(1500);

    } catch (InterruptedException e) {
        Thread.currentThread.interrupt();
    }
}

或更简单的是仅捕获循环外的异常。

try {
    while (!Thread.currentThread().isInterrupted()) {
        Thread.sleep(1500);
    }
} catch (InterruptedException e) {
    Thread.currentThread.interrupt();
}
<小时/>

编辑:我认为这只是一个练习,因为使用 ExecutorService 会简单得多

public static void main(String[] args) throws InterruptedException {
    ExecutorService service = Executors.newSingleThreadExecutor();

    for (String message : "a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z".split(",")) {
        System.out.println(getThreadName() + ": Sending " + message);
        service.submit(() -> {
            System.out.println(getThreadName() + ": Recevied " + message);
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                System.out.println("--- Interrupted");
            }
        });
    }
    service.shutdown();
    service.awaitTermination(1, TimeUnit.SECONDS);
    service.shutdownNow();
}

public static String getThreadName() {
    return Thread.currentThread().getName();
}

打印

main: Sending a
main: Sending b
main: Sending c
main: Sending d
main: Sending e
main: Sending f
main: Sending g
main: Sending h
main: Sending i
main: Sending j
main: Sending k
main: Sending l
main: Sending m
main: Sending n
main: Sending o
main: Sending p
main: Sending q
main: Sending r
main: Sending s
main: Sending t
main: Sending u
main: Sending v
main: Sending w
main: Sending x
main: Sending y
main: Sending z
pool-1-thread-1: Recevied a
pool-1-thread-1: Recevied b
--- Interrupted

关于java - sleep 时线程中断,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36258649/

相关文章:

java - 尝试使用平板电脑下载时,我的 Android 应用程序不支持设备

java - 同步增加一个 int 值

linux - 一个多线程进程的线程ID可以和另一个正在运行的进程的进程ID相同吗?

c++ - 如何使用多线程读取文件?

multithreading - Matlab多核

java - JPA 连接限制

java - 使用 Gradle 的 JAR 中的 META-INF/服务

java - JComboBox 返回值

java - 如何在 Java 中创建一个不同时运行某些任务的线程池?

multithreading - 是否仍然需要验证异步请求的标准模式?