1

念のため。私は Java Concurrency in practice book に従っています。特に最終的に安全に公開する場合、最初に参照が他のすべてのスレッドに表示され、次に公開されたオブジェクトの状態が他のすべてのスレッドに表示されることは明らかですが、ここでの問題は、参照された配列要素は、公開された状態で表示されることが保証されていますか? (確かに、誰もそれらのデータ オブジェクトを変更しない限り)。

例:

@Mutable
public class NotThreadsafeDataObject {

    private String message;

    public NotThreadsafeDataObject (String message) {
        this.message = message;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

}

それでは、可変オブジェクトの配列を安全に公開しましょう。

public class Publish {

    public final NotThreadsafeDataObject[] publish;

    public Publish() {
        publish = new NotThreadsafeDataObject[] { new NotThreadsafeDataObject("one"), new NotThreadsafeDataObject("two")};

    }

}
4

2 に答える 2

0

配列内の個々の変更可能なオブジェクトの値を変更できると確信しています。いえ

publish[0].setMessaage("Hello");

うまくいくでしょう。また、配列からオブジェクトを削除できると思います。宣言されているため、変更できないのは配列参照ですfinal。完全に不変のコレクションが必要な場合は、final として宣言された List を操作し、新しい別の List を作成してデータを入力し、メソッドpublic static List unmodifiableList(List list) を使用してそれを最終的なリストに割り当てます。

ublic class Publish {

    public static final List<NotThreadsafeDataObject> publish;

    static {
        init();
    }  

    private static void synchronized init() {
       List<NotThreadsafeDataObject> list = new ArrayList<>();
       list.add(new NotThreadsafeDataObject("one");
       list.add(new NotThreadsafeDataObject("two");
       publish = Collections.unmodifiableList(list);
    }  
}

これにより、防弾の完全に不変のリストが作成され、それへの参照もその内容も変更できなくなります。

于 2017-04-03T16:09:00.540 に答える
0

「Java Concurrency in Practice」で提示された用語で言えば、配列は「実質的に不変」なオブジェクトです。このようなオブジェクトでは、内部状態を壊さないようにするために、安全なパブリケーションが常に必要です。安全な公開を使用しているため、コードは問題ありません。より具体的には、「final」キーワード メモリ セマンティクスは、final フィールドにアクセスするスレッドが、フィールドが書き込まれる前に発生したすべてのことを確認することを保証します (「happen-before」が確立されます)。

于 2017-04-03T15:49:00.500 に答える