我正在创建多个线程,我希望每个线程在其BlockingQueue中监听任何新消息2秒,然后消失。我使用了以下代码:
public class Main {
public static void main(String[] argv) throws Exception {
int capacity = 10;
BlockingQueue<String> queue = new ArrayBlockingQueue<String>(capacity);
ArrayList<String> names = new ArrayList<String>();
names.add("Apple"); names.add("Banana"); names.add("Mango");
HashMap<String, Worker> workermap = new HashMap<String, Worker>();
for (String name: names) {
Worker a_worker = new Worker(queue);
a_worker.setName(name);
a_worker.start();
workermap.put(name, new Worker(queue));
}
queue.put("Hello ");
}
}
class Worker extends Thread {
BlockingQueue<String> q;
Worker(BlockingQueue<String> q) {
this.q = q;
}
public void run() {
try {
long start = System.currentTimeMillis();
long end = start + 2*1000;
while (true) {
String x = q.take();
if(System.currentTimeMillis()>=end){
System.out.println("No new message since two seconds, killing thread " + this.getName());
Thread.interrupted();
// break;
}
// if (x == null) {
// break;
// }
System.out.println(x + "from " + this.getName());
}
} catch (InterruptedException e) {
}
}
}
我希望输出是这样的:
Hello from Apple
Hello from Banana
Hello from Mango
No new message since two seconds, killing thread Apple
No new message since two seconds, killing thread Banana
No new message since two seconds, killing thread Mango
但我只得到了Hello from Apple
,然后就什么都没有了。该过程继续进行,没有任何进一步的输出。除了使用计时器终止线程之外,我还尝试检查队列元素是否为空,但没有成功。我哪里错了?
发布于 2018-06-22 23:23:09
如前所述,您需要使用interrupt
而不是thread
(),而且您不能使用Thread.interrupted();
来使用池。您需要使用Thread.currentThread().interrupt();
。此外,您不需要检查时间,因为BlockingQueue#poll
将等待2
秒。
while (!Thread.currentThread().isInterrupted()) {
String x = q.poll(2, TimeUnit.SECONDS);
if (x == null)
System.out.println("No new message since two seconds, killing thread " + this.getName());
Thread.currentThread().interrupt();
System.out.println(x + "from " + this.getName());
}
输出:
No new message since two seconds, killing thread Mango
Hello from Mango
No new message since two seconds, killing thread Apple
nullfrom Apple
No new message since two seconds, killing thread Banana
nullfrom Banana
编辑:然而,我相信你根本不需要循环。只要下面的代码就可以很好地为你工作。
public void run() {
try {
String x = q.poll(2, TimeUnit.SECONDS);
if (x == null)
System.out.println("No new message since two seconds, killing thread " + this.getName());
System.out.println(x + "from " + this.getName());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
发布于 2018-06-23 02:48:58
我只是试着对你的代码进行最小限度的修复:
import java.util.ArrayList;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
public class Main {
public static void main(String[] argv) throws Exception {
int capacity = 10;
BlockingQueue<String> queue = new ArrayBlockingQueue<String>(capacity);
ArrayList<String> names = new ArrayList<String>();
names.add("Apple"); names.add("Banana"); names.add("Mango");
for (String name: names) {
Worker a_worker = new Worker(queue);
a_worker.setName(name);
a_worker.start();
}
queue.put("Hello");
queue.put("Bonjour");
}
}
class Worker extends Thread {
BlockingQueue<String> q;
Worker(BlockingQueue<String> q) {
this.q = q;
}
public void run() {
long start = System.currentTimeMillis();
long end = start + 2; //just wait for two milliseconds
while (true) {
String x = q.poll();
if(x != null) {
System.out.println(x + " from " + this.getName());
} else if(System.currentTimeMillis() >= end){
System.out.println("No new message since two milliseconds, killing thread " + this.getName());
interrupt();
}
if(interrupted()) {
break;
}
}
}
}
示例输出:
Hello from Apple
No new message since two milliseconds, killing thread Banana
Bonjour from Mango
No new message since two milliseconds, killing thread Apple
No new message since two milliseconds, killing thread Mango
https://stackoverflow.com/questions/50990795
复制相似问题