0

正しく同期されたプログラムはまだデータ競合を許可しますか?(パートI)での議論では、 2つの非常に良い例があります。

2つ目について話したいだけです。便宜上、ここに2番目の例を示します。

public int hashCode() {
    if (hash == 0 && count > 0) { //(1)
        int h = hash;
        int off = offset;
        char val[] = value;
        int len = count;

        for (int i = 0; i < len; i++) {
            h = 31*h + val[off++];
        }
        hash = h; //(2)
    }
    return hash; //(3)
}

発生前の関係の定義の最初の項目によると、xとyが同じスレッドのアクションであり、プログラムの順序でxがyの前にある場合、hb(x、y)、次の結論が得られる可能性があります。

hb((1)、(2))とhb((2)、(3))があるため、hb((1)、(3))です。

なぜなら:

ハッシュは共有変数です。

(1)、(2)、(3)はすべて同じスレッドのアクションです。

プログラム順に、(1)が(2)の前に、(2)が(3)の前に来る。

さて、私の質問に戻りましょう。(1)と(3)の間に起こる前の関係がある場合、(1)と(3)は決して並べ替えるべきではありません。

私の説明に誤解はありますか?あなたの意見はどうですか?

4

1 に答える 1

2

異なるスレッドによってコミットされた(1)、(2)、および(3)から発生するアクションに課せられる順序はありません。唯一発生するのは、注文前に、 JLS 17.4.5に従って、同じスレッドによってコミットされた(1)、(2)、(3)のトリプレット内にあることです。

xとyが同じスレッドのアクションであり、プログラムの順序でxがyの前にある場合、hb(x、y)。

マシン命令の並べ替えは、それらを実行するスレッドがプログラムの順序と矛盾する順序を観察しない限り、どの実行でも発生する可能性があります。他のスレッドに関しては、これらのアクションから他のスレッドのアクションに移る前に、何も起こらないので、アクションを任意の順序で監視できます(またはまったく監視しません) 。ただし、この例には1回の書き込みしか含まれておらず、「順序が狂っている」という概念に意味を与えるには、少なくとも2回の書き込みが必要になります。書き込みアクションのみが、他のスレッドから観察できる効果を持ちます。

于 2012-08-26T12:30:53.313 に答える