0

としてパラメータを取るメソッドを作成する必要がありますmaxValue。0 からループしますが、一度 1 つのインデックスを使用すると、それを再度使用してはなりません。

説明:

例を見てみmaxValueましょう。これは 2000 です。これで 0 から 2000 になるはずですが、開始インデックスは他のスレッドによって変更され続けます。0 になるか、1900 年または 1999 年になるか、 未満の任意の数値になりmaxValueます。したがって、インデックスの開始から終了までループを維持し、残りのアイテムをループする必要があります。

これが私が試したことです:

public int i = 0;  //keep changes by other thread

public void DoStuff(int maxValue) {
    HashSet<Integer> valuesSet = new HashSet<Integer>();      

    // fill hashset
    for (int a = 0; a < maxValue; a++)
        valuesSet.add(a);       

    for (; i < maxValue; i++) {
        if (valuesSet.contains(i)) {
            valuesSet.remove(i);
            // SomeMethod(i);
        }

        if (valuesSet.isEmpty())// must check isEmpty first
            break;
        if (i == (maxValue - 1)) // reset i to 0 to use remaining items in hashset
            i = 0;
    }
}

maxValue私はこのコードをテストしていませんが、他のスレッドが i を 0 またはそれより小さい値に設定し続け、このループが無限になると問題が発生することがわかります。それはもっと良いものでなければなりませんが。アイデアはありますか?

編集:
深い例
i=0maxValue=2000

DoStuff が呼び出され、iループを介して 100 に達するとi、他のスレッドによって 1600 に設定され、ループは続行されますがi、同じ他のスレッドによって再び 30 に設定され、何度も何度も他のスレッドによって設定されます。valuesSet呼ばれるSomeMethod(i)valuesSetしかし、問題は、 1998 年や 1999 年のように 1 つ以上の項目が残っていて、i0、10、100 のように低く設定され続けると、ループが中断または終了する可能性が非常に低くなることです。

私が望むのは、数値(0からmaxValue)が一度呼び出されたSomeMethod場合、再度呼び出されてはならず、開始番号は変化し続けSomeMethod、maxValueまでのすべての数値で呼び出されている必要があるということです。SomeMethodmaxValue まで呼び出され、まだ番号が残っている場合は、最小の番号から再度開始する必要があります。

4

1 に答える 1

0

Iteratorあなたの要件は明確ではありませんが、カスタムクラスとして実装する必要があるものを記述しているようです。例えば:

public class MyIterator<T> implements Iterator<T> {
    private int maxValue;
    private int pos;
    private List<T> list;
    public ListIterator(List<T> list, int maxValue) { 
        this.list = list; 
        this.maxValue = maxValue;
    }

    public synchronized T next() {
        if (pos < list.size() && pos <= maxValue) {
            return list.get(pos++);
        } else {
            throw ...
        }
    }

    // etcetera.
}

次に、反復に参加できるようにする特定のスレッドに、このクラスのインスタンスを提供します。他のスレッドは干渉できません。実際、他のスレッドは別のインスタンスを使用できます...そして独立して反復します。

このカスタム イテレータと によって返されるものとの唯一の違いは次のとおりであることに注意してくださいList.iterator()

  • これは 0 から maxValue まで繰り返すだけです。
  • これにはsynchronizedメソッドがあり、複数のスレッドで共有できます。

必要に応じてメソッドを追加することもできresetます。

于 2013-01-20T04:27:40.947 に答える