【发布时间】:2016-02-13 17:07:00
【问题描述】:
我正在制作一个程序来检查字符串是否包含在目录树和文本文件中,并且我使用生产者-消费者模式。不幸的是,除非我添加打印语句,否则我的消费者线程不想停止。我尝试了一切 - 同步,使字段易失,但仍然找不到问题。
public class Producer
extends Thread
{
private volatile Storage store;
private volatile Reader read;
Producer(Storage store, Reader read){
this.read = read;
this.store = store;
}
public void run()
{
while (!read.isEmpty()) {
String FileName = read.returnAllPaths().peek().getFileName().toString();
String item = null;
try {
item = read.returnAllPaths().take().toString();
} catch (InterruptedException e1) {
e1.printStackTrace();
}
File currentFile = new File(item);
try (BufferedReader reader = new BufferedReader(new FileReader(currentFile))) {
String line;
while ((line = reader.readLine()) != null) {
FileAndLine current = new FileAndLine(FileName, line);
store.fillStore(current);
}
} catch (IOException e) {
e.printStackTrace();
}
}
store.setEndOfPaths(true);
}
}
public class Consumer
extends Thread
{
private volatile Storage store;
private String clue;
public Consumer(Storage store, String clue){
this.store = store;
this.clue = clue;
}
public void run()
{
FileAndLine currentLine;
while(!store.isEndOfPaths() || !store.isEmpty()){
currentLine = store.depleteStore();
System.out.println("q");
if(currentLine.line.contains(clue))
System.out.println(currentLine.FileName + ": " + currentLine.line);
}
}
}
public class Storage {
private BlockingQueue<FileAndLine> Store;
private boolean full;
private volatile boolean endOfPaths;
public Storage(){
Store = new LinkedBlockingQueue<FileAndLine>();
full = false;
}
private boolean isFull(){
return full;
}
public synchronized BlockingQueue<FileAndLine> getStore(){
return this.Store;
}
public synchronized boolean isEmpty(){
return Store.isEmpty();
}
public synchronized void setEndOfPaths(boolean set){
endOfPaths = set;
}
public synchronized boolean isEndOfPaths(){
return endOfPaths;
}
public synchronized void fillStore(FileAndLine line){
while(isFull()){
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
Store.add(line);
full = false;
notifyAll();
if(Store.size() == 1000){
full = true;
}
}
public synchronized FileAndLine depleteStore(){
FileAndLine line;
if(endOfPaths == true && Store.isEmpty())
{
return new FileAndLine("", "");
}
while(Store.isEmpty())
{
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
line = new FileAndLine(Store.remove());
if(Store.size() < 1000){
full = false;
notifyAll();
}
return line;
}
}
【问题讨论】:
-
您正在测试
read.isEmpty(),这需要是线程安全的。 -
我看不出这里的基本逻辑是什么,但我怀疑你可以用一个 parallelStream 替换所有这些。
标签: java multithreading synchronized