1

私は、Javaメソッドの同期とオブジェクトのロックに関係することに興味があります。

同期されたメソッドを呼び出すと、私が理解していることから、メソッド呼び出しの間、オブジェクト全体がロックされます。

これは、オブジェクトにデータを書き込むメソッドのみを同期する必要があり、オブジェクトからデータを読み取る必要がないことを意味しますか?

public class testclass {

    private ArrayList<String> data;

    public ArrayList<String> getData() {
        return data;
    }

    public synchronized void setData(ArrayList<String> data) {
        this.data = data;
    }
}

基本的に、上記のコードはスレッドセーフですか(setDataメソッドの実行中にtestclassオブジェクトがロックされるため)?または、getDataメソッドも同期する必要がありますか?

4

3 に答える 3

3

これは、オブジェクトにデータを書き込むメソッドのみを同期する必要があり、オブジェクトからデータを読み取る必要がないことを意味しますか?

いいえ-読み取りを同期しない場合、可視性の保証はありません(オブジェクトの古いバージョンを取得する可能性があります)。

注:あなたの場合、各メソッドはアトミックであるため、synchronizedキーワードを使用する必要はありませんdata。代わりに、単にvolatileにすることができます。

于 2012-09-17T09:23:57.833 に答える
2

ロックはオブジェクト自体をロックするのではなく、オブジェクトに関連付けられたモニターです。あなたの場合、メソッドgetDataの同期でさえ、テストクラススレッドを安全にしません。これは、「データ」フィールドのインスタンスをワイルドワールドに返し、多くのスレッドがオブジェクトを予期しない順序で実行する可能性があるためです。

「可視性」に従うには、「データ」を揮発性にするか、両方のメソッドを同期する必要があります。JVMはバイトコードを自由に最適化できるため、一部のスレッドは「古い」データを見ることができます。

于 2012-09-17T09:26:01.757 に答える
1

synchronize getData()あるスレッドが最初に呼び出しgetData()、別のスレッドがメソッドを実行したいwriteData()ときに、スレッドがロックされないという保証がない場合は、どのような保証がありますか。したがって、スレッドセーフではありません。

[編集]そして、他に指定されているように、不揮発性のDataオブジェクトを返すこともスレッドセーフではありません。これは、このクラスの外部で非スレッドセーフな方法で変更される可能性があります。

于 2012-09-17T09:28:16.873 に答える