我有一个FileScanner线程,它在列表中添加新文件,多个FileParser线程获取新文件,每个线程都解析自己的文件。为了同步,我将添加到列表中并从同步资源块中的列表中读取。问题是,有时FileScanner Thread似乎饿死,并且没有进入synchronized块,等待其他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>();
}
}
答案 0 :(得分:2)
线程优先级是一个提示或建议,可能会也可能不会产生影响。因此,依靠优先级设置来确定并发程序的正确性是危险的。
来自“Java Concurrency In Practice”(Goetz等人):
避免使用线程优先级的诱惑,因为它们可能会增加平台依赖性并导致活动问题。[...]
如果您的程序遇到死锁,则并发逻辑存在问题。更改线程优先级(不太可能是最好的情况)会掩盖该问题或(在可能的情况下)引入未确定的硬件特定行为。
您的问题的描述,似乎是ReadWriteLock的主要示例。但是如果没有代码的简洁示例,很难给出合理的建议。
答案 1 :(得分:1)
线程优先级不应该成为或中断同步。听起来像是阻塞集合中的问题,无论如何你都不应该自己实现。在java.util.concurrent中查看LinkendBlockingQueue和朋友。
答案 2 :(得分: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;
}
}