【发布时间】:2013-07-17 09:27:56
【问题描述】:
我的 WebApplication 中有下面这段代码,每当用户登录应用程序时,它基本上都会这样做。
- addSymbols 方法将在用户登录操作期间被调用。
- 由于上述原因,PriorityBlockingQueue 被启动
- PriorityBlockingQueue 将符号添加到 HashSet 中,然后对其进行迭代以在该新添加的符号上运行特定任务。
我在这里面临的问题是,作为 HashSet 一部分的 while 循环一遍又一遍地执行相同的任务,因为它处于线程的 while true 条件内。
我正在粘贴示例输出以了解与之相关的上下文。
Symbol From priorityBlocking SymbolTest
Symbol From allSymbolsSet SymbolTest
Symbol From allSymbolsSet SymbolTest
Symbol From allSymbolsSet SymbolTest
Symbol From allSymbolsSet SymbolTest
Symbol From allSymbolsSet SymbolTest
Symbol From allSymbolsSet SymbolTest
Symbol From allSymbolsSet SymbolTest
Symbol From allSymbolsSet SymbolTest
Symbol From allSymbolsSet SymbolTest
Symbol From allSymbolsSet SymbolTest
这是我完成上述操作的代码。
package com;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.PriorityBlockingQueue;
public class TaskerThread extends Thread {
private PriorityBlockingQueue<String> priorityBlocking = new PriorityBlockingQueue<String>();
private Set<String> allSymbolsSet = new HashSet<String>();
ExecutorService es = Executors.newFixedThreadPool(2);
public void addSymbols(String str) {
if (str != null) {
priorityBlocking.add(str);
}
}
public void run() {
while (true) {
try {
while (priorityBlocking.peek() != null) {
String symbol = priorityBlocking.poll();
allSymbolsSet.add(symbol);
try {
System.out.println("Symbol From priorityBlocking" +" "+ symbol);
} catch (Exception e) {
e.printStackTrace();
}
}
Iterator<String> ite = allSymbolsSet.iterator();
while (ite.hasNext()) {
String symbol = ite.next();
if (symbol != null && symbol.trim().length() > 0) {
try {
System.out.println("Symbol From allSymbolsSet"+" "+symbol);
} catch (Exception e) {
e.printStackTrace();
}
}
}
Thread.sleep(2000);
} catch (Exception e) {
e.printStackTrace();
}
}
}
public static void main(String args[]) {
try {
TaskerThread qT = new TaskerThread();
qT.start();
qT.addSymbols("SymbolTest");
} catch (Exception e) {
e.printStackTrace();
}
}
}
如果有什么方法可以让迭代器任务只运行一次,请告诉我。
【问题讨论】:
-
我不能在while true条件之外保留迭代部分代码,因为如果我这样做,如果任何新用户登录,我将错过要执行的任务。
-
不确定它是否能解决任何问题,但您可能想使用
take或poll(long,TimeUnit),因为它们会阻止。当队列中没有任何内容时,这将阻止循环运行。然后你应该也可以删除手册sleep。 -
您在 allSymbolsSet 中添加了符号,但您从不删除它们。因此,在您的 while(true) 内,您将始终打印所有符号
-
@fluminis 如何从 allSymbolsSet 中删除符号?因为每个用户都有一个独特的符号。
标签: java multithreading