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 Concurrency In Practice」(Goetz et al) から:

スレッドの優先度を使用する誘惑は避けてください。プラットフォームへの依存度が高まり、活性の問題が発生する可能性があるためです。[...]

プログラムでデッドロックが発生した場合は、同時実行ロジックに問題があります。スレッドの優先順位を変更すると、(おそらく最良のケースではありませんが) その問題が隠蔽されるか、(可能性の高いケースでは) 未確定のハードウェア固有の動作が導入されます。

問題の説明は、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 に答える