0

次のコードでは、出力が 3 行しかないのにThread-0、出力が 6 行になるのはなぜですか?Thread-1

public class NameList{

    private List names = new ArrayList();
    public synchronized void addName(String name){
        names.add(name);
    }

    public synchronized void print(){
        for (int i = 0; i < names.size(); i++) {
            System.out.print(names.get(i)+" ");
            System.out.println(Thread.currentThread().getName());
        }
    }

    public static void main(String args[]){

        final NameList nl = new NameList();
        for (int i = 0; i <2; i++) {

            new Thread(){
                public void run(){
                    nl.addName("A");
                    nl.addName("B");
                    nl.addName("C");
                    nl.print();
                }
            }.start();

        }
    }
}

出力:

A Thread-1
B Thread-1
C Thread-1
A Thread-0
B Thread-0
C Thread-0
A Thread-0
B Thread-0
C Thread-0
4

2 に答える 2

6

Thread-0 が 6 回出力し、thread-1 が 3 回出力するのはなぜですか?????

各スレッドはの数に基づいてメッセージを吐き出しているためNameList.names:

// the threads share the same `NameList`
final NameList nl = new NameList();
...
nl.addName("A");
...
for (int i = 0; i < names.size(); i++) {

はスレッド間で共有されるためnames、両方のスレッドでリストを変更しています。最初のスレッドは 3 つの名前を追加し、2 番目のスレッドが実行される前に終了する必要があります。次に、2 番目の 1 つがさらに 3 を追加し、6 を吐き出します。

2 つのスレッドが同じリストを更新するようにしたい場合は、並行コレクションを使用するか、synchronized (names) {ブロック内で追加を行うことによって保護する必要があります。System.out.print()同期されたクラスであるため、コードが機能しているため、スレッド間でメモリが更新されます。print()呼び出しを削除すると、names実行時に各スレッドが空として表示される可能性が高くなります。また、Listが破損したり、その他の不具合が発生したりする可能性もあります。

なぜ3 beforeThread-1を吐き出すのかというと、スレッドが同時に起動されており、どちらが先かという競合状態です。 Thread-0

于 2013-08-22T22:44:07.607 に答える
0

各スレッドは 3 つの名前をリストに追加しているため、2 番目のスレッドが実行された後、6 つの名前が追加され、2 つのスレッドの 1 つがそれらすべてを出力します。

于 2013-08-22T22:51:14.603 に答える