线程,永远不会结束
这里是我的代码:线程,永远不会结束
public class BigFileReader implements Runnable {
private final String fileName;
int a = 0;
private final BlockingQueue<String> linesRead;
public BigFileReader(String fileName, BlockingQueue<String> linesRead) {
this.fileName = fileName;
this.linesRead = linesRead;
}
@Override
public void run() {
try {
//since it is a sample, I avoid the manage of how many lines you have read
//and that stuff, but it should not be complicated to accomplish
BufferedReader br = new BufferedReader(new FileReader(new File("E:/Amazon HashFile/Hash.txt")));
String str = "";
while((str=br.readLine())!=null)
{
linesRead.put(str);
System.out.println(a);
a++;
}
} catch (Exception ex) {
ex.printStackTrace();
}
System.out.println("Completed");
}
}
public class BigFileProcessor implements Runnable {
private final BlockingQueue<String> linesToProcess;
public BigFileProcessor (BlockingQueue<String> linesToProcess) {
this.linesToProcess = linesToProcess;
}
@Override
public void run() {
String line = "";
try {
while ((line = linesToProcess.take()) != null) {
//do what you want/need to process this line...
String [] pieces = line.split("(...)/g");
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public class BigFileWholeProcessor {
private static final int NUMBER_OF_THREADS = 2;
public void processFile(String fileName) {
BlockingQueue<String> fileContent = new LinkedBlockingQueue<String>();
BigFileReader bigFileReader = new BigFileReader(fileName, fileContent);
BigFileProcessor bigFileProcessor = new BigFileProcessor(fileContent);
ExecutorService es = Executors.newFixedThreadPool(NUMBER_OF_THREADS);
es.execute(bigFileReader);
es.execute(bigFileProcessor);
es.shutdown();
}
}
此代码是好的,但有一个主要的问题。也就是说,线程永远不会结束!即使整个过程已经完成,我仍然可以保证程序还活着。这里有什么问题?
将阻塞,直到元素可用:
获取并移除此队列的头,如果需要的话,直到元素变得可用等待。
所以经过BigFileReader读完输入文件,并把在BlockingQueue的线条,BigFileProcessor将在新的输入法take()
永远等待。
你可能想找到一种方法来通知BigFileProcessor会有没有更多的投入不断提上了BlockingQueue的,可能是通过增加a sentinel value到队列或者找到一些其他的方式来告诉BigFileProcessor停止呼叫take()
。
的定点方法的一个例子:
public class BigFileReader implements Runnable {
public static final String SENTINEL = "SENTINEL"; //the actual value isn't very important
...
while((str=br.readLine())!=null) {
linesRead.put(str);
}
//when reading the file is done, add SENTINEL to the queue
linesRead.put(SENTINEL);
}
//inside BigFileProcessor...
while ((line = linesToProcess.take()) != null) {
// check if value in queue is sentinel value
if (line == BigFileReader.SENTINEL) {
//break out of the while loop
break;
}
//otherwise process the line as normal
}
另一种方法可以是使用the overload of poll
that takes a timeout value代替take()
,并具有逻辑是BigFileProcessor打破它的循环,如果它不能从队列中读什么超过N秒等。
这是我第一次处理这个问题。我不知道该怎么做。你能告诉我吗? –
@GloryOfSuccess查看示例更新 –
太好了。谢谢。 –
BlockingQueue顾名思义就是阻塞的。一旦你执行了queue.take(),线程就会挂起,直到队列中有东西要占用。为了终止线程,您需要使用队列.isEmpty()来知道队列中是否还有消息。我建议您在完成读取文件后发送文件结束消息,以便知道何时退出循环。
你有什么证据表明它永远不会结束?你如何提交'Runnable'? –
开始之前,setDeamon(true)。 – robermann
与实际问题无关,但'a ++'[可能]不是线程安全的。您应该使用AtomicInteger代替。 – yshavit