0

2 つのスレッドが使用されている場合、出力順序が元の配列の順序と同じであることを確認するにはどうすればよいですか? 「0 1 2 3 4 5 6 7 8 9」と出力したいのですが、現在順番が保証されていません。順番に作る方法はありますか?本当にありがとうございました。

public class Test {
    public static void main(String[] args){
        DataStore dataStore = new DataStore();
        for(int i=0; i<10; i++){
            dataStore.add(String.valueOf(i));
        }
        CopyThread t1 = new CopyThread(dataStore);
        CopyThread t2 = new CopyThread(dataStore);
        t1.start();
        t2.start();

        try {
            t1.join();
            t2.join();
        } catch(Throwable t) {
        }
    }   
}

class CopyThread extends Thread {
    private DataStore data; 

    public CopyThread(DataStore data){
        this.data = data;
    }
    public void run(){      
        DataStore.Line line = null;
        int lineID;

        while( (line = data.getLine()) != null ){       
            lineID = line.id;       
            System.out.println(Thread.currentThread().getName() + ": " + lineID);       
        }   
    }
}

class DataStore {
    ArrayList<String> lines = new ArrayList<String>();
    int current = 0;

    public synchronized Line getLine () {
        if (current >= lines.size()) {
            return null;
        }
        Line line = new Line(lines.get(current), current);
        current++;

        return line;
    }

    public synchronized void add (String s) {
        lines.add(s);
    }

    public synchronized int size () {
        return lines.size();
    }

    public static class Line {
        public String line;
        public int id;

        public Line (String str, int i) {
            line = str;
            id = i;
        }
    }
}
4

2 に答える 2

1

ArrayList の代わりに Vector を試してください。

ベクター

Vector クラスは、拡張可能なオブジェクトの配列を実装します。配列と同様に、整数インデックスを使用してアクセスできるコンポーネントが含まれています。ただし、Vector のサイズは、Vector の作成後に項目を追加および削除するために、必要に応じて拡大または縮小できます。

各ベクトルは、容量と capacityIncrement を維持することにより、ストレージ管理を最適化しようとします。容量は常に少なくともベクトル サイズと同じ大きさです。コンポーネントがベクターに追加されると、ベクターのストレージが capacityIncrement のサイズのチャンクで増加するため、通常はより大きくなります。アプリケーションは、多数のコンポーネントを挿入する前にベクトルの容量を増やすことができます。これにより、増分再割り当ての量が減少します。

Vector の iterator および listIterator メソッドによって返される Iterator はフェイルファストです。Iterator の作成後に、Iterator 自体の remove メソッドまたは add メソッド以外の方法で Vector が構造的に変更された場合、Iterator は ConcurrentModificationException をスローします。したがって、同時変更に直面した場合、Iterator は、将来の不確定な時点で恣意的で非決定論的な動作を危険にさらすのではなく、迅速かつ明確に失敗します。Vector の elements メソッドによって返される列挙型は、フェイルファストではありません。

イテレータのフェイルファスト動作は保証できないことに注意してください。一般的に言えば、同期されていない同時変更が存在する場合にハードな保証を行うことは不可能であるためです。フェイルファスト イテレーターは、ベスト エフォート ベースで ConcurrentModificationException をスローします。したがって、その正確性をこの例外に依存するプログラムを作成するのは誤りです。反復子のフェイルファスト動作は、バグを検出するためだけに使用する必要があります。

于 2013-04-14T08:26:42.460 に答える
0

同期を使用してそれを実現できます。

synchronized(data) {
  while( (line = data.getLine()) != null ){       
        lineID = line.id;       
        System.out.println(Thread.currentThread().getName() + ": " + lineID);       
  }
}
于 2013-04-14T09:17:34.730 に答える