コア同時実行:何CASこと?Java8はCASを最適化する方法ですか?私はあなたがプレー理解していません

あなたは、CASがあるため基本的な実装との契約の原則のことを言うことができる、あなたはJavaで読むと契約したい場合は、そのコアが最初機構CASを理解することで、Javaとの契約に発言権を聞いたことがあります。

今日はあなたがCASは、そのアトミック操作だけでなく、どのようなCAS Java8の最適化を確保することであるかを理解かかります。

同期:オーバーキル

数行のコードで見てみましょう:

public class CASTest {
    static int i = 0;

    public static void increment() {
        i++;
    }
}

私インクリメント操作を実行するには、100個のスレッドを同時にインクリメントを呼び出す()メソッドがある場合、結果は私が100だろうか?

学びマルチスレッドの学生は、このメソッドはスレッドセーフではありませんことを、私は++ではないので、知っておくべきアトミック操作、100を取得することは困難です。

ビット100(知られているが、スキップ可能)がありません理由を説明、私はこの操作を++、コンピュータは3つの段階に分けて実行する必要があります。
1、iの値を読み取ります。
2は、iを1だけ増加させる
3、最終結果は、メモリIに書き込まれます。スレッドAが値を読み取る場合したがって、I I = 0、またBスレッド今回はI 0 = Iの値を読み出します。その後、A iが1にインクリメントされ、I = 1のときに、メモリに書き込まれます。その後、私は、その後、B iはメモリに書き込まれた1は、スレッドBのI、I = 1のこの時点でメモリを=であるスレッドBであることが1だけインクリメントされます。すなわち、スレッドAで、B iが以来増加しているが、最終的な結果は1ではなく2です。

次に、どのようにそれを行うには?次のように解決する戦略は、一般的に、この方法にロックを追加しています

public class CASTest {
    static int i = 0;

    public synchronized static void increment() {
        i++;
    }
}

同期を添加した後、あなただけの増分を入力することができますつのスレッドを持つことができます()メソッドを持っています。このように、それは、スレッドセーフでない表示されません。:私はこの記事を参照することができ、同期理解していない徹底的に(ヘビー級をロックするためにバイアスされたロックから)同期知ってもらいます

ロックが取得するときに、このメソッドをインクリメント競争する多くのスレッドがあるsynchronizedキーワードを加えた後、同期の同期のほかにしかし、単純なインクリメント演算子、少しやり過ぎのように感じ、されるブロックされたそれらを覚ますために、最終的には、この方法を、ブロッキング/これらの操作は非常に時間がかかる目覚めます。

ここではいくつかは、まだたくさんの最適化を行っていない後JDK1.6に同期させる、と言うかもしれませんか?A:はい、それは本当にこれらの増加は、競争に、コストはまだたくさんあるときに多くのスレッド、あなたは別の記事を紹介してくれたと信じていない場合でも、しかし偏っロック、軽量ロックなどが増加し、最適化の多くを行っています彼らは完全に同期します(ロックにヘビー級からバイアスロック)

CAS:私には、このような些細な問題

そこ代わり同期方法をロックする他の方法はありません、そして増分を確保すること()メソッドは、スレッドセーフですか?

私たちは、私がこのように次のように使用している場合、増分はスレッドセーフであることを保証することができ、見て?次のステップ:

iの値は、この時点で0であれば1、スレッドは、メモリからのIの値を読み出して、我々は、すなわちケースK = 0、それK値と呼ばれます。

2、その結果、J = K + 1。

メモリ内の値k Iと比較して3、およびそれらが等しい場合、私の他のスレッド変更された値は、我々はメモリに書き込まれた値(この場合は1)Jを入れないことは、この手段と等しくない場合(私の平均値)は、他のスレッドによって変更されている、我々はメモリに書き込まれたjの値を持っていないだろうが、再びこれら3つの操作を継続するために戻ってステップ1にジャンプします。

コードワードに変換これは次のようになります。

public static void increment() {
    do{
        int k = i;
        int j = k + 1;
    }while (compareAndSet(i, k, j))
}

あなたがシミュレーションに行けば、あなたは、書き込みスレッドセーフでしょう。

いくつかは,,,自分自身でこのステップは、スレッドセーフああではないメモリや他の操作に書き込み、メモリを読んで、だけでなく、比較的乾燥し、この操作だけではなく、ここでのcompareAndSetの第三の工程を言うかもしれませんか?

こののcompareAndSet操作、彼実際にのみ対応するオペレーティングシステムのことであるあなたが本当にこのプロセスをシミュレートするために考えなければならないことを、このショーを考えることができますが、私はあなたに伝えたい場合は、ハードウェアの取扱説明書、多くの操作にそこ見えるが、内部が、オペレーティングシステム上で、彼はアトミック実行されることを保証することができます。

英語での超長命令語のために、我々は我々がのcompareAndSetと呼ば置くので、短いために彼を呼び出すためにそれを使用したいCASこと。

それが起こるように、この機構CAS文言の使用は、このように、より良いプログラムの実行を行うことができ、物事の支障はありませんでした、ロックしない競争があると言うことができる、スレッドセーフです。

Javaでは、このクラスはまた、例えば、CAS原子を提供します。

  1. AtomicBoolean
  2. AtomicInteger
  3. AtomicLong
  4. AtomicReference

どのようにそれを使うのか?次のように改訂されました、私は上記の例を取ると、コードは次のとおりです。

public class CASTest {
    static AtomicInteger i = new AtomicInteger(0);

    public static void increment() {
        // 自增 1并返回之后的结果
        i.incrementAndGet();
    }
}

CAS:密かに私の値を変更

このCASのメカニズムがインクリメント()メソッドを保証することができ、いくつかの問題が依然として存在するがスレッド場合、例えば、第3のステップは、iの値を下げる直後、実行されようと、スレッドB I値プラス1であります私が変更されていないので、図1に示すように、次に実行を第3工程をスレッド、誰がスレッド考え、この時間は、私の変更された値です。そして、それは我々が通常言うことであるABAの問題を

基本タイプの値については、この元の値の後ろにデジタルの変化はあまり影響はありませんが、それは参照型のためであれば、それは上の巨大な影響を与えるだろう。

バージョンにそれを制御します

ABAは、この問題を解決するために、我々はバージョン管理を導入することができ、例えば、毎回スレッドが修正2つのスレッドが同じ参照を保持するものの、参照バージョンの値は、更新されますが、彼らはそう、異なるバージョンを持っています、我々は、ABAの問題を防ぐことができます。JavaはこのクラスAtomicStampedReference、バージョン管理を行うことができます提供します。

CASのJava8最適化。

すべてのスレッドがインクリメント()このメソッドを入力することができますので、このCASの結果としてのロック方法のためのメカニズムは、ありません、この方法にあまりにも多くのスレッドが、問題があるだろうとします。実行されるスレッドがあるたびに第三段階、iの値が常に変更されたとき、スレッドので、最初からやり直すために最初のステップに戻るには続けています。

糸密度が高すぎる、あまりにも多くの人々は、iの値を変更したいので、その後、ほとんどの人は無駄サイクルリソース消費で、失敗した変更します:これは、問題が発生します。

この問題を解決するために、Java8はセル[]配列を導入し、その作業メカニズムはこれです:5つのスレッドがある場合、私は、インクリメント演算を実行する可能性が低い、その後5つのスレッド、なぜなら、相反のないたくさんの、その後、彼らはそれからCASを使用することにより、これまでのように通常に従ってみましょう。

Iインクリメント演算子になるように100件のスレッドが存在する場合は、次に、今回、衝突が大幅に増加するが、システムは、移動セルアレイ要素のこれらの異なるスレッドに割り当てる、もし細胞[10]その中に10個の要素がありますおよび要素を初期化すると、システムは、10個のグループにインクリメント動作を行うセル配列の各要素を100個のスレッドを置く、0であるため、セルアレイの最終的な値は10の要素は10でありますこのシステムの値は、二つが、私100は、自己増力操作した100件のスレッドに相当する、100を得るために、素子10及び最終的にまとめられています。

もちろん、私はちょうどここJava8 CASの一般的な原理を説明するために例を与えるに特異的に我々はソースに行くことができ、あるいはああ、対応する記事を検索するために興味を持っている最適化されています。

概要

原則のCASの理解が非常に重要であり、それはAQSの礎石であり、AQSは、並行処理フレームワークの基礎となるものです、次回は、私は記事AQSを書きます。

ブラザー・デイは、私がよく書かれて感じれば、好むかもしれません

1、私に注意を払うオリジナルマイクロチャネル公共番号「プログラム再生するにはハンサムな書き込みに焦点を当て、毎日時間プッシュ乾燥技術記事の」アルゴリズム + 基本的なコンピュータの知識(コンピュータネットワーク+ + Linuxはデータベース+オペレーティングシステム)、私は注意を聞いたが、良いではありませんああ傑出したになります。

2、私は聖歌を賛美ポイントには、とても多くの人々が道で、この記事を見ることができる、喜喜を私にインスピレーションを得ました。

公開された79元の記事 ウォンの賞賛20000 + ビュー163万+

おすすめ

転載: blog.csdn.net/m0_37907797/article/details/104710698