1

最近、セマフォとマルチスレッドをいじっていましたが、配列リストで奇妙なことが起こっていることに気付きました。詳細:

単一のプライベート ArrayList を持つクラスがあります。

public class NewClass{

    private ArrayList list = new ArrayList();

    public void put(Object val){
        list.add(val);
    }

    public void del(Object val){
        list.remove(val);
    }
}

いくつかのスレッドから、要素を削除しようとしています (その前に何も置かずに):

public class SomeClass {

    public static void main(String[] args) throws InterruptedException {
        new SomeClass();
    }

    public SomeClass() throws InterruptedException {
        Thread tr2 = new Thread() {
            @Override
            public void run() {
                NewClass nc = new NewClass();
                for (int i = 0; i < 100; i++) {
                        nc.del(i);
                }
            }
        };
        tr2.start();
    }
}

そして、スレッドが機能し始めると、エラーも例外もありません。一方、デバッグの場合、その list.indexOf(val); がはっきりとわかります。-1 値を返します - 実際には存在しませんが、「削除」されています。ここで何が起こっているのか誰でも説明できますか?

4

4 に答える 4

0

コメントするには長すぎます:

  • NewClassインスタンスはスレッド間で共有されず、各インスタンスは 1 つのスレッドからのみアクセスされます。
  • List.remove(int index)空のリストを呼び出しても特別なことは何もありません (-1 を返します)。
于 2013-07-11T12:04:39.730 に答える
0

あなたが言ったように、「ものをいじる」のように。

ArrayList の 2 つのメソッドの間に挟まれているのではないかと疑っています。

 public E remove(int index) // throws exception 

and 

 public boolean remove(Object o) // doesn't throws exception

スレッドを介してアクセスしているときは、実際には参照のようにオブジェクトとして渡しています。実際には、例外をスローしない remove(Object o) メソッドを呼び出します。

シングルスレッドプログラムをいじりながら、直接呼び出していると思います

list.remove(int) /// 実際に IndexOutOfBoundsException をスローするメソッド。

例外をスローするコードを提供していないため、これは私の仮定にすぎません

于 2013-07-11T15:11:34.863 に答える