gpt4 book ai didi

Java:如何在中断后无限期地让线程回到 sleep 状态?

转载 作者:行者123 更新时间:2023-11-29 09:52:33 25 4
gpt4 key购买 nike

我正在编写 Java 软件,它只有一个线程,可以监听外部按钮被按下的情况。如果按下按钮,该线程会通知其他线程,否则它只会 hibernate 。

我的模型是使用中断驱动设计。理想情况下我想做只要没有按下按钮,线程就会 sleep 。当按下按钮时,我希望线程做一些工作并返回 hibernate 状态。

谁能确认/更正以下实现

// This is a code that interrupt-driven thread will execute
public void run() {
while (true) {
try {
Thread.sleep(1000); // Sleeps only for 1s. How to sleep indefinitely?
} catch (InterruptedException exception) {
process(exception); // Doing some work
// then going back to sleep using the while loop
}
}
}

此外,在终端中单击每个按钮后,我都会收到一条消息

I/O exception raised from stop()

此消息是什么意思(即如果我捕获异常,为什么打印它)?可以避开终端打印吗?

最佳答案

如果您使用异常来控制程序流程,通常会被认为是一种代码味道。

此问题的正确解决方案是使用事件处理程序从中读取的事件的BlockingQueue。这通常称为生产者/消费者。

public class TwoThreads {

public static void main(String args[]) throws InterruptedException {
System.out.println("TwoThreads:Test");
new TwoThreads().test();
}

// The end of the list.
private static final Integer End = -1;

static class Producer implements Runnable {

final BlockingQueue<Integer> queue;

public Producer(BlockingQueue<Integer> queue) {
this.queue = queue;
}

@Override
public void run() {
try {
for (int i = 0; i < 1000; i++) {
queue.add(i);
Thread.sleep(1);
}
// Finish the queue.
queue.add(End);
} catch (InterruptedException ex) {
// Just exit.
}
}

}

static class Consumer implements Runnable {

final BlockingQueue<Integer> queue;

public Consumer(BlockingQueue<Integer> queue) {
this.queue = queue;
}

@Override
public void run() {
boolean ended = false;
while (!ended) {
try {
Integer i = queue.take();
ended = i == End;
System.out.println(i);
} catch (InterruptedException ex) {
ended = true;
}
}
}

}

public void test() throws InterruptedException {
BlockingQueue<Integer> queue = new LinkedBlockingQueue<>();
Thread pt = new Thread(new Producer(queue));
Thread ct = new Thread(new Consumer(queue));
// Start it all going.
pt.start();
ct.start();
// Wait for it to finish.
pt.join();
ct.join();
}

}

不要让自己对这有多少代码感到困惑 - 其中大部分只是包装。核心功能是:

开始 - 创建一个 BlockingQueue 并在两个线程之间共享它。

    BlockingQueue<Integer> queue = new LinkedBlockingQueue<>();
Thread pt = new Thread(new Producer(queue));
Thread ct = new Thread(new Consumer(queue));

当事件发生时,发布到队列。

                queue.add(i);

事件处理程序从队列中获取数据。

        while (!ended) {
try {
Integer i = queue.take();

请注意,take 将阻塞,直到发布事件发生中断。

关于Java:如何在中断后无限期地让线程回到 sleep 状态?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35202329/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com