0

我有一个 FileScanner 线程,它在列表中添加新文件和多个 FileParser 线程,它们获取新文件并每个解析自己的文件。为了同步,我将添加到列表中并从同步资源块中的列表中读取。问题是有时 FileScanner 线程似乎饿死并且没有进入同步块等待其他 FileParser 线程释放资源(列表)。我的问题是,如果我将最大优先级设置为 FileScanner,将最小优先级设置为其他 FileParser 线程,它会解决问题吗?换句话说,线程优先级是否会影响 JVM 在线程中进行选择以授予对同步块的访问权限?谢谢。

更新:

private List<ScannerFile> scannedFiles = Collections.synchronizedList(new LinkedList<ScannerFile>()) ;

这在我的 FileScanner 线程中调用:

    synchronized(scannedFiles){
        for(ScannerFile f: newList)
            try{
                scannedFiles.add(f);
            }
            catch(ConcurrentModificationException e){
                logger.error(e);
            }
    }

这在我的 FileParser 线程中调用:

synchronized(scannedFiles){
    try{
        for(ScannerFile f: scannedFiles){
            if(parserName.equals(f.getParserName()) && f.isNew() == true){
                listNewFiles.add(f);
            }           
        }
        return listNewFiles;
    }
    catch(ConcurrentModificationException e){
        logger.trace(e);
        return new ArrayList<ScannerFile>();
    }
}
4

3 回答 3

2

线程优先级是一个提示或建议,可能会或可能不会产生影响。因此,依赖优先级设置来保证并发程序的正确性是很危险的。

来自“实践中的 Java 并发”(Goetz 等人):

避免使用线程优先级的诱惑,因为它们会增加平台依赖性并可能导致活性问题。[...]

如果你的程序遇到死锁,说明并发逻辑有问题。更改线程优先级将(在不太可能的最佳情况下)掩盖该问题或(在可能的情况下)引入未确定的硬件特定行为。

您的问题的描述看起来像是ReadWriteLock的主要示例。但是如果没有简洁的代码示例,就很难给出合理的建议。

于 2013-02-16T11:04:31.320 回答
1

线程优先级不应建立或中断同步。听起来像是您的阻塞集合中的一个问题,无论如何您都不应该自己实现。看看 java.util.concurrent 中的 LinkendBlockingQueue 和朋友。

于 2013-02-16T11:14:13.040 回答
0

存在逻辑错误。这应该可以工作(我没有要重新确认的 IDE):

LinkedBlockingQueue<ScannerFile> newList = new LinkedBlockingQueue<>();
LinkedBlockingQueue<ScannerFile> scannedFiles = new LinkedBlockingQueue<>();
for(;;){

try{
ScannerFile f = newList.get();
scannedFiles.add(f);
}
catch(InterruptedException ex{
Thread.currentThread.interrupt();
//log
break;
}
}

ThreadParser会这样:

for(;;){
try{
ScannedFile f= scannedFiles.get();
//other logic goes here
}catch(InterruptedException ex{
Thread.currentThread.interrupt();
//log
break;
}
}
于 2013-02-18T06:56:09.690 回答