2

開発中のアプリケーションに問題があります。
Prod と Cons の 2 つのスレッドがあり、それぞれが shared に書き込み、読み取りますQueue。ここではすべてかなり標準的です。
このアプリケーションの目的は、Prod がファイルを読み取り、各行を に追加することですQueue。一方、Cons はこれらの行を読み取り、ペアで「照合」する必要があります (いくつかの基準に従って)。

問題は、Cons がその役割を果たすために、 からいくつかの行を「処理」し Queue、ペアを形成するものだけを削除する必要があることです。たとえば、以下がQueueProd によって埋められた Q であるとします。

Q:
-
A1  
A2  
B1  
C1  
D1  
C2  
D2    
B2  
E1  
E2

コンスはペア (A1,A2)、(B1,B2)、(C1,C2) などを作成する必要があります (ペアの順序は必須です)。

私の問題は、Pair (B1,B2) を作成するには、まず Cons が C1、D1、D2、および C2 を分析し、それらが B1 と一致しないことを確認する必要があることです。次に B2 が見つかり、B1 と B2 の両方を Q から削除する必要があります。ただし、以前の一致しない要素 (C1、D1 など) の順序は変更されません。
現時点では、キューから常に最初の要素を削除する Cons で解決しました。それが一致しない場合は、Cons の追加の内部キューに保存されます。一致する要素が見つかると、ペアが作成され、内部キューに保存されたすべての要素が Q (実際には a ) の先頭に「再注入」されDeQueます。

このアプローチは単純な状況では機能しますが、どうしようもなく欠点があります。Prod が実行され続けると、Cons が一致しない要素を削除している間に、Prod が新しい行を追加し、Cons が Q にメッセージを再挿入しようとする瞬間に事実上デッドロックが発生する可能性があります。

また、Cons は Q の要素を「のぞいて」、一致する要素のみを削除することしかできないと考えていましたが、それはDeque.

誰でも問題について提案がありますか? 必要なことを実行する をいつでも「作成」できますDequeが、本当にしたくないのです。ミスしすぎ…

ありがとう!

4

2 に答える 2

1

マッチングの実行方法によっては (たとえば、「C1」が指定された場合、「C146」などではなく「C2」でなければならないことがわかっている場合)、Queueを「C1」のLinkedHashMapに置き換えることが理にかなっている場合があります。 " や "C2" などをキーとして使用します。プロデューサは要素をLinkedBlockingQueueに(最大容量なしで) 追加しますが、コンシューマはキューをポーリングして使用しますContainsKeyハッシュマップで、一致する要素が既にマップにあるかどうかを判断します。一致する場合は、一致する要素がマップから削除されます。一致しない場合は、現在の要素がマップに追加されます。コンシューマがすべてのプロデューサ データの処理を終了すると、LinkedHashMap にはすべての一致しない要素の順序付きリストが含まれます。「C2」を「C1」に、「C1」を「C2」に一致させることができることを確認してください。

public class SharedCollections {
    public static LinkedBlockingQueue<Object> workList = new LinkedBlockingQueue<>();
}

public class Producer implements Runnable {
    public void run() {
        while(true) {
            SharedCollections.workList.offer(obj);
        }
    }
}

public class Consumer implements Runnable {
    LinkedHashMap<String, Object> hashMap = new LinkedHashMap<>();
    public void run() {
        while(true) {
            Object obj = SharedCollections.workList.take(); // blocks if the workList is empty
            String matchingId = getMatchingId(obj.id); // e.g. returns "C2" if the object's id is "C1"
            if(hashMap.containsKey(matchingId)) {
                hashMap.remove(matchingId);
            } else {
                hashMap.put(obj.id, obj);
            }
        }
    }
}
于 2013-04-25T13:48:14.677 に答える