「同期」とはどういう意味ですか?


994

synchronizedキーワードの使用法と重要性について質問があります。

  • synchronizedキーワードの意味は何ですか?
  • メソッドはいつすべきsynchronizedですか?
  • プログラム的にも論理的にもどういう意味ですか?


1
ハッシュマップとハッシュテーブルの間の役立つディスカッション、および同期:stackoverflow.com/questions/40471/java-hashmap-vs-hashtable
limc


1
最初のコメントからドキュメントリンク全体を調べましたが、最後の段落に到達するまで理解できませんでした。リンクを貼り付けて何も引用しない代わりに、リンクを貼り付けて引用を追加する方が便利です。
Rakib

回答:


878

synchronizedキーワードは、異なるスレッドに関するすべてが同じ変数、オブジェクトおよびリソースへの読み書きです。これはJavaの簡単なトピックではありませんが、Sunからの引用です:

synchronized メソッドは、スレッドの干渉とメモリの一貫性エラーを防ぐための簡単な戦略を可能にします。オブジェクトが複数のスレッドから見える場合、そのオブジェクトの変数へのすべての読み取りまたは書き込みは、同期されたメソッドを介して行われます。

非常に小さな一言で言えば、同じ「リソース」に対して読み取りと書き込みを行う2つのスレッド(たとえば、という変数foo)がある場合、これらのスレッドがアトミックな方法で変数にアクセスすることを確認する必要があります。なければsynchronized、キーワード、あなたのスレッド1に対して行った変更のスレッド2が表示されないことがありfoo、あるいは悪化し、それは半分だけ変更することができます。これはあなたが論理的に期待するものではありません。

繰り返しますが、これはJavaの重要なトピックです。詳細については、SOおよびインターウェブに関する以下のトピックを参照してください。

「ブライアンゲッツ」という名前が脳の「並行性」という用語に永続的に関連付けられるまで、これらのトピックを探索していきます。


71
それで、基本的にこのSynchronizedキーワードはあなたのメソッドをスレッドセーフにしますか?
Rigo Vides

82
synchronizedキーワードは、コードスレッドを安全にするツールの1つです。それ自体でメソッドまたは変数で同期を使用するだけでも、うまくいく場合とそうでない場合があります。Javaメモリモデルの基本を理解することは、同時実行性を正しくするために非常に重要です。
Stu Thompson、

28
あなたがBrian Goetz(またはおそらくJon Skeet)でない限り、言語プリミティブ(同期、揮発性)だけでJavaの並行性を正しくすることはほとんど不可能です。まず、java.util.concurrentパッケージを利用して、その上にビルドします。
ティロ

12
より明確に:同期されたメソッドを複数のスレッドから同時に呼び出すことはできません。
peterh-モニカを2016年

2
@peterh synchronizedはそれ以上のことを行うため、より詳細な説明
Stu Thompson

294

まあ、理論的な説明は十分にあると思うので、このコードを検討してください。

public class SOP {
    public static void print(String s) {
        System.out.println(s+"\n");
    }
}

public class TestThread extends Thread {
    String name;
    TheDemo theDemo;
    public TestThread(String name,TheDemo theDemo) {
        this.theDemo = theDemo;
        this.name = name;
        start();
    }
    @Override
    public void run() {
        theDemo.test(name);
    }
}

public class TheDemo {
    public synchronized void test(String name) {
        for(int i=0;i<10;i++) {
            SOP.print(name + " :: "+i);
            try{
                Thread.sleep(500);
            } catch (Exception e) {
                SOP.print(e.getMessage());
            }
        }
    }
    public static void main(String[] args) {
        TheDemo theDemo = new TheDemo();
        new TestThread("THREAD 1",theDemo);
        new TestThread("THREAD 2",theDemo);
        new TestThread("THREAD 3",theDemo);
    }
}

注:synchronized前のスレッドの実行が終了していない限り、次のスレッドによるメソッドtest()の呼び出しをブロックします。スレッドはこのメソッドに一度に1つずつアクセスできます。synchronizedすべてのスレッドがなければ、このメソッドに同時にアクセスできます。

スレッドがオブジェクトの同期メソッド 'test'(ここでオブジェクトは 'TheDemo'クラスのインスタンス)を呼び出すと、そのオブジェクトのロックが取得されます。新しいスレッドは、前のスレッドである限り、同じオブジェクトの同期メソッドを呼び出すことはできません。ロックを取得したものはロックを解除しません。

クラスの静的同期メソッドが呼び出されたときにも同様のことが起こります。スレッドは、クラスに関連付けられたロックを取得します(この場合、そのオブジェクトレベルのロックがまだ使用可能なため、そのクラスのインスタンスの非静的同期メソッドは、どのスレッドでも呼び出すことができます)。現在ロックを保持しているスレッドによってクラスレベルのロックが解放されない限り、他のスレッドはクラスの静的同期メソッドを呼び出すことができません。

同期した出力

THREAD 1 :: 0
THREAD 1 :: 1
THREAD 1 :: 2
THREAD 1 :: 3
THREAD 1 :: 4
THREAD 1 :: 5
THREAD 1 :: 6
THREAD 1 :: 7
THREAD 1 :: 8
THREAD 1 :: 9
THREAD 3 :: 0
THREAD 3 :: 1
THREAD 3 :: 2
THREAD 3 :: 3
THREAD 3 :: 4
THREAD 3 :: 5
THREAD 3 :: 6
THREAD 3 :: 7
THREAD 3 :: 8
THREAD 3 :: 9
THREAD 2 :: 0
THREAD 2 :: 1
THREAD 2 :: 2
THREAD 2 :: 3
THREAD 2 :: 4
THREAD 2 :: 5
THREAD 2 :: 6
THREAD 2 :: 7
THREAD 2 :: 8
THREAD 2 :: 9

同期せずに出力

THREAD 1 :: 0
THREAD 2 :: 0
THREAD 3 :: 0
THREAD 1 :: 1
THREAD 2 :: 1
THREAD 3 :: 1
THREAD 1 :: 2
THREAD 2 :: 2
THREAD 3 :: 2
THREAD 1 :: 3
THREAD 2 :: 3
THREAD 3 :: 3
THREAD 1 :: 4
THREAD 2 :: 4
THREAD 3 :: 4
THREAD 1 :: 5
THREAD 2 :: 5
THREAD 3 :: 5
THREAD 1 :: 6
THREAD 2 :: 6
THREAD 3 :: 6
THREAD 1 :: 7
THREAD 2 :: 7
THREAD 3 :: 7
THREAD 1 :: 8
THREAD 2 :: 8
THREAD 3 :: 8
THREAD 1 :: 9
THREAD 2 :: 9
THREAD 3 :: 9

7
良い例、理論を知るのは良いことですが、コードは常により具体的で完全です。
サンティイグレシアス2016

2
@SantiIglesias「完全」ですか?いいえ。この例はのロック動作を示してsynchronizedいますが、メモリの一貫性は無視されます。
Stu Thompson

2
@Stu Thompsonのメモリの一貫性はロックの結果です
Dheeraj Sachan

@DheerajSachanそのロジックにより、ReentrantLockを使用すると、メモリの整合性が確保されます。そうではありません。
Stu Thompson

3
@boltup_im_coding:start()メソッドは、スレッドを「実行可能」状態にします。つまり、実行の準備ができているか、すでに実行されています。Runnable状態の別のスレッド(通常は、必ずしも優先順位が高いとは限りません)がキューをジャンプして実行を開始することがあります。上記の例では、THREAD 3はTHREAD 2.前にCPUを取得するために起こった
サヒールJ

116

synchronizedキーワードが複数のスレッドによってコードまたはオブジェクトのブロックへの同時アクセスを防止します。すべてのメソッドはHashtableあるsynchronizedので、一度に1つのスレッドしかそれらのいずれかを実行することができ、。

などの非synchronized構成要素を使用する場合、HashMap一貫性エラーを防ぐために、コードにスレッドセーフ機能を構築する必要があります。


81

synchronizedマルチスレッド環境では、synchronizedメソッド/ブロックを持つオブジェクト は、2つのスレッドsynchronizedがコードのメソッド/ブロックに同時にアクセスすることを許可しません。つまり、別のスレッドが更新している間、あるスレッドは読み取ることができません。

代わりに、2番目のスレッドは、最初のスレッドがその実行を完了するまで待機します。オーバーヘッドは速度ですが、利点はデータの一貫性が保証されることです。

ただし、アプリケーションがシングルスレッドの場合、synchronizedブロックは利点を提供しません。


54

synchronizedキーワードは、(それが静的メソッドである場合を除き、指定されたオブジェクトインスタンスの)唯一のスレッドが同時にメソッドを実行できるように、メソッドを入力するときにスレッドがロックを取得させます。

これは、クラスをスレッドセーフにすることと呼ばれますが、これは婉曲表現です。同期によってベクターの内部状態が破損するのを防ぐことは事実ですが、これは通常、ベクターのユーザーにはあまり役立ちません。

このことを考慮:

 if (vector.isEmpty()){
     vector.add(data);
 }

関係するメソッドは同期されていますが、個別にロックおよびロック解除されているため、残念ながら2つのタイミングスレッドが2つの要素を持つベクトルを作成できます。

したがって、実際には、アプリケーションコードでも同期する必要があります。

メソッドレベルの同期は、a)不要な場合は高価であり、b)同期が必要な場合は不十分であるため、非同期の置換(Vectorの場合はArrayList)があります。

最近になって、同時実行パッケージがリリースされ、マルチスレッドの問題を処理する多数の巧妙なユーティリティが追加されました。


27

概観

Javaの同期キーワードは、スレッドセーフ、つまり複数のスレッドが同じ変数を読み書きする場合に関係しています。
これは、直接(同じ変数にアクセスすることにより)または間接的に(同じ変数にアクセスする別のクラスを使用するクラスを使用することにより)発生する可能性があります。

synchronizedキーワードは、複数のスレッドが同じ変数に安全にアクセスできるコードブロックを定義するために使用されます。

もっと深く

構文的には、synchronizedキーワードはObjectそのままのパラメーター(ロックオブジェクトと呼ばれます)を取り、その後にが続き{ block of code }ます。

  • 実行がこのキーワードに遭遇すると、現在のスレッドはロックオブジェクトを "lock / acquire / own"(選択)し、ロックが取得された後、関連するコードブロックを実行しようとします。

  • 同期コードブロック内の変数への書き込みはすべて、同じロックオブジェクトを使用して同期コードブロック内のコードを同様に実行する他のすべてのスレッドに確実に表示されます

  • 一度に1つのスレッドのみがロックを保持できます。その間、同じロックオブジェクトを取得しようとする他のすべてのスレッドは待機します(実行を一時停止します)。ロックは、実行が同期コードブロックを終了するときに解放されます。

同期されたメソッド:

synchronizedキーワードをメソッド定義に追加することは、ロックオブジェクトthis (たとえば、メソッド)およびClassInQuestion.getClass() (クラスメソッド)である同期コードブロックにラップされているメソッド本体全体と同じです。

-インスタンスメソッドはstaticキーワードを持たないメソッドです。
-クラスメソッドはstaticキーワードを持つメソッドです。

テクニカル

同期しないと、読み取りと書き込みの順序が保証されず、変数が不要なままになる可能性があります。
(たとえば、変数は、1つのスレッドによって書き込まれたビットの半分と別のスレッドによって書き込まれたビットの半分で終了し、どちらのスレッドも書き込みを試みなかった状態に変数を残しますが、両方を組み合わせた混乱です。)

ハードウェアが変数の値をキャッシュしている可能性があるため、別のスレッドが(壁時計時間)前にスレッドで書き込み操作を完了するだけでは十分ではなく、読み取りスレッドは書き込まれた内容ではなく、キャッシュされた値を参照します。それ。

結論

したがって、Javaの場合、スレッド化エラーが発生しないようにするために、Javaメモリモデルに従う必要があります。
言い換えると、内部でそれらを使用する同期、アトミック操作、またはクラスを使用します。

出典

http://docs.oracle.com/javase/specs/jls/se8/html/index.htmlJava®
言語仕様、2015年2月13日


申し訳ありませんが、この例はありますが、意味がわかりません。`Integer i1 = Arrays.asList(1,2,3,4,5).stream()。findAny()。get(); synchronized(i1){Integer i2 = Arrays.asList(6,7,8,9,10).parallelStream().sorted().findAny()。get(); System.out.println(i1 + "" + i2); } `1.最初のインスタンスでブロックを呼び出したのはなぜですか?この呼び出しはコードに影響を与えませんか?2.最初のブロックの呼び出しにもかかわらず、2番目のインスタンスはスレッドセーフになりますか?
Adryr83

1
@ Adryr83質問がある場合は、新しい質問を投稿して質問することができます。しかし、ここにいるので、私は何ができるかを分析します(質問は理解するのが少し難しいです)。そのコードの一部について私が言えることから、同期を必要とするものは何も含まれていないようです。コンテキスト外です。提案:可能であれば、コードをより小さな個々の部分に分割してから、それらについての回答を検索してください。1つの大きなコードブロックを理解するよりも、小さな孤立した問題を理解する方がはるかに簡単です。
ジーマ

21

サッカー場で見かけるような改札口のようなものだと考えてください。入りたい人々の平行する流れがありますが、回転木戸でそれらは「同期」されます。一度に通過できるのは1人だけです。乗り越えたい人はすべてやってくれますが、乗り切るまで待つ必要があるかもしれません。


16

同期キーワードとは何ですか?

スレッドは、主にフィールドとフィールド参照オブジェクトが参照するオブジェクトへのアクセスを共有することで通信します。この形式の通信は非常に効率的ですが、スレッド干渉とメモリ整合性エラーの 2種類のエラーが発生する可能性があります。これらのエラーを防ぐために必要なツールは同期です。

同期されたブロックまたはメソッドは、スレッドの干渉を防ぎ、データの整合性を確保します。いつでも、ロックを取得することにより、同期されたブロックまたはメソッド(クリティカルセクション)にアクセスできるスレッドは1つだけです。他のスレッドは、クリティカルセクションにアクセスするためのロックの解放を待ちます。

メソッドはいつ同期されますか?

メソッドはsynchronized、メソッド定義または宣言に追加すると同期されます。メソッド内で特定のコードブロックを同期することもできます。

プログラム的にも論理的にもどういう意味ですか?

つまり、ロックを取得してクリティカルセクションにアクセスできるスレッドは1つだけです。このスレッドがこのロックを解放しない限り、他のすべてのスレッドはロックの取得を待機する必要があります。ロックを取得せずにクリティカルセクションにアクセスすることはできません。

これは魔法ではできません。アプリケーションの重要なセクションを特定し、それに応じて保護するのはプログラマの責任です。Javaは、アプリケーションを保護するためのフレームワークを提供しますが、保護するすべてのセクションの場所と内容はプログラマーの責任です。

Javaドキュメントページからの詳細

組み込みロックと同期:

同期は、組み込みロックまたはモニターロックと呼ばれる内部エンティティを中心に構築されます。組み込みロックは、同期の両方の側面で役割を果たします。オブジェクトの状態への排他的アクセスを強制し、可視性に不可欠な発生前の関係を確立します。

すべてのオブジェクトには、固有のロックが関連付けられています。慣例により、オブジェクトのフィールドへの排他的で一貫性のあるアクセスを必要とするスレッドは、オブジェクトにアクセスする前にオブジェクトの固有ロックを取得し、それらが完了したら固有ロックを解放する必要があります。

スレッドは、ロックを取得してからロックを解放するまでの間に、固有のロックを所有していると言います。スレッドが固有のロックを所有している限り、他のスレッドは同じロックを取得できません。他のスレッドは、ロックを取得しようとするとブロックされます。

スレッドが組み込みロックを解放すると、そのアクションとその後の同じロックの取得との間に発生前の関係が確立されます。

メソッドを同期させると、2つの効果があります。

まず、同じオブジェクト上で同期されたメソッドの2つの呼び出しをインターリーブすることはできません。

1つのスレッドがオブジェクトの同期メソッドを実行しているとき、同じオブジェクトの同期メソッドを呼び出す他のすべてのスレッドは、最初のスレッドがオブジェクトで完了するまでブロックします(実行を中断します)。

第2に、同期メソッドが終了すると、同じオブジェクトの同期メソッドの後続の呼び出しと、前に発生する関係が自動的に確立されます。

これにより、オブジェクトの状態の変更がすべてのスレッドから見えるようになります。

で同期する他の方法を探します。

Javaで同期(これ)を避けますか?


11

Synchronized normal methodSynchronized statement(これを使用する)と同等

class A {
    public synchronized void methodA() {
        // all function code
    }

    equivalent to

    public void methodA() {
        synchronized(this) {
             // all function code
        }
    } 
}

Synchronized static methodSynchronized statement(クラスを使用)と同等

class A {
    public static synchronized void methodA() {
        // all function code
    }

    equivalent to

    public void methodA() {
        synchronized(A.class) {
             // all function code
        }
    } 
}

同期ステートメント(変数を使用)

class A {
    private Object lock1 = new Object();

    public void methodA() {
        synchronized(lock1 ) {
             // all function code
        }
    } 
}

の場合synchronized、との両方がSynchronized MethodsありSynchronized Statementsます。ただし、Synchronized Methodsと似ているSynchronized Statementsため、理解する必要があるだけですSynchronized Statements

=>基本的に、

synchronized(object or class) { // object/class use to provides the intrinsic lock
   // code 
}

ここに2つが理解に役立つと思います synchronized

  • すべてのオブジェクト/クラスにはintrinsic lock関連付けられています。
  • スレッドがを呼び出すとsynchronized statementintrinsic lockそのsynchronized statement'sオブジェクトのが自動的に取得され、メソッドが戻るときに解放されます。限りスレッドが所有しているようにintrinsic lock他のスレッドが取得することができないSAMEロック=>スレッドセーフ。

=> thread A呼び出し時=> 同じロックのためsynchronized(this){// code 1}、have synchronized(this)およびall synchronized normal method(クラス内)のすべてのブロックコード(クラス内)がロックされます。ロック解除後に実行されます( "// code 1"が終了します)。 thread A

この動作はsynchronized(a variable){// code 1}またはに似ていsynchronized(class)ます。

SAME LOCK => lock(どのメソッドに依存していないか、またはどのステートメントに依存していないか)

同期メソッドまたは同期ステートメントを使用しますか?

synchronized statementsそれはより拡張可能であるため、私は好みます。たとえば、将来的には、メソッドの一部のみを同期する必要があります。たとえば、2つの同期されたメソッドがあり、互いに関連するものはありませんが、スレッドがメソッドを実行すると、他のメソッドをブロックします(使用することで防ぐことができますsynchronized(a variable))。

ただし、同期メソッドの適用は単純で、コードは単純に見えます。一部のクラスでは、同期化されたメソッドが1つだけ、またはクラス内のすべての同期化されたメソッドが相互に関連しています=> synchronized methodコードを短く簡単に理解するために使用できます

注意

(にはあまり関係ありません。synchronizedオブジェクトとクラスの違い、または非静的と静的の違いです)。

  • あなたが使用している場合synchronizedや、通常の方法またはsynchronized(this)またはsynchronized(non-static variable)その各オブジェクトインスタンスにベースを同期します。
  • あなたが使用する場合synchronizedまたは静的メソッドまたはsynchronized(class)またはsynchronized(static variable)そのクラスにベースを同期します

参照

https://docs.oracle.com/javase/tutorial/essential/concurrency/syncmeth.html https://docs.oracle.com/javase/tutorial/essential/concurrency/locksync.html

それが役に立てば幸い


11

これは、Javaチュートリアルの説明です。

次のコードを検討してください。

public class SynchronizedCounter {
    private int c = 0;

    public synchronized void increment() {
        c++;
    }

    public synchronized void decrement() {
        c--;
    }

    public synchronized int value() {
        return c;
    }
}

countインスタンスの場合、SynchronizedCounterこれらのメソッドを同期させると、2つの効果があります。

  • まず、同じオブジェクト上で同期されたメソッドの2つの呼び出しをインターリーブすることはできません。1つのスレッドがオブジェクトの同期メソッドを実行しているとき、同じオブジェクトの同期メソッドを呼び出す他のすべてのスレッドは、最初のスレッドがオブジェクトで完了するまでブロックします(実行を中断します)。
  • 第2に、同期メソッドが終了すると、同じオブジェクトの同期メソッドの後続の呼び出しと、前に発生する関係が自動的に確立されます。これにより、オブジェクトの状態の変更がすべてのスレッドから見えるようになります。

9

私が理解しているように、同期は基本的に、コンパイラーがメソッドの周囲にmonitor.enterおよびmonitor.exitを書き込むことを意味します。そのため、使用方法によってはスレッドセーフになる可能性があります(つまり、クラスの動作によってはスレッドセーフではない同期メソッドでオブジェクトを作成できるということです)。


5

他にどのような答えが不足していることは、1つの重要な側面である:メモリの障壁。スレッドの同期は、基本的に2つの部分で構成されます:シリアル化と可視性。「jvmメモリーバリア」は簡単ではなく、非常に重要なトピックであるため(複数のスレッドによってアクセスされる共有データを変更する場合)、すべてのユーザーにグーグルすることをお勧めします。それが終わったら、明示的な同期の使用を回避するのに役立つjava.util.concurrentパッケージのクラスを確認することをお勧めします。これにより、プログラムをシンプルかつ効率的に保ち、デッドロックを防ぐことさえできます。

そのような例の1つがConcurrentLinkedDequeです。コマンドパターンと一緒に使用すると、コマンドを並行キューに詰め込むことで非常に効率的なワーカースレッドを作成できます-明示的な同期は不要、デッドロックは不可能、明示的なsleep()は不要、take()を呼び出してキューをポーリングするだけです。

つまり、「メモリ同期」は、スレッドを開始したり、スレッドが終了したり、揮発性変数を読み込んだり、モニターのロックを解除したり(同期されたブロック/関数を残したり)すると、暗黙的に発生します。この「同期」は、ある意味で「フラッシュ」に影響します")その特定のアクションの前に行われたすべての書き込み。前述のConcurrentLinkedDequeの場合、ドキュメントは次のように述べています。

メモリの一貫性の影響:他の並行コレクションと同様に、オブジェクトをConcurrentLinkedDequeに配置する前のスレッドでのアクションは、別のスレッドでのその要素のアクセスまたはConcurrentLinkedDequeからの削除に続くアクションの前に発生します。

多くの経験のないほとんどのJavaプログラマーは、それが原因で与え​​られたとおりに多くのことを行うため、この暗黙の動作はやや悪質な側面です。そして、Javaが別の作業負荷がある本番環境で「想定」されていることを実行していないときに、このスレッドに突然つまずき、同時実行の問題をテストするのはかなり困難です。


3

同期とは、単一のオブジェクトに関連付けられている複数のスレッドが、特定のオブジェクトで同期ブロックが使用されている場合にダーティな読み取りと書き込みを防止できることを意味します。より明確にするために、例を見てみましょう:

class MyRunnable implements Runnable {
    int var = 10;
    @Override
    public void run() {
        call();
    }

    public void call() {
        synchronized (this) {
            for (int i = 0; i < 4; i++) {
                var++;
                System.out.println("Current Thread " + Thread.currentThread().getName() + " var value "+var);
            }
        }
    }
}

public class MutlipleThreadsRunnable {
    public static void main(String[] args) {
        MyRunnable runnable1 = new MyRunnable();
        MyRunnable runnable2 = new MyRunnable();
        Thread t1 = new Thread(runnable1);
        t1.setName("Thread -1");
        Thread t2 = new Thread(runnable2);
        t2.setName("Thread -2");
        Thread t3 = new Thread(runnable1);
        t3.setName("Thread -3");
        t1.start();
        t2.start();
        t3.start();
    }
}

2つのMyRunnableクラスオブジェクトを作成しました。runnable1はスレッド1と共有され、スレッド3&runnable2はスレッド2のみと共有されます。同期が使用されずにt1とt3が開始すると、PFB出力は、スレッド1と3の両方が同時にvar値に影響することを示唆します。スレッド2の場合、varは独自のメモリを持っています。

Without Synchronized keyword

    Current Thread Thread -1 var value 11
    Current Thread Thread -2 var value 11
    Current Thread Thread -2 var value 12
    Current Thread Thread -2 var value 13
    Current Thread Thread -2 var value 14
    Current Thread Thread -1 var value 12
    Current Thread Thread -3 var value 13
    Current Thread Thread -3 var value 15
    Current Thread Thread -1 var value 14
    Current Thread Thread -1 var value 17
    Current Thread Thread -3 var value 16
    Current Thread Thread -3 var value 18

Synchronziedを使用すると、すべてのシナリオでスレッド3がスレッド1の完了を待機します。取得されるロックは2つあり、1つはスレッド1とスレッド3によって共有されるrunnable1にあり、もう1つはスレッド2のみが共有するrunnable2にあります。

Current Thread Thread -1 var value 11
Current Thread Thread -2 var value 11
Current Thread Thread -1 var value 12
Current Thread Thread -2 var value 12
Current Thread Thread -1 var value 13
Current Thread Thread -2 var value 13
Current Thread Thread -1 var value 14
Current Thread Thread -2 var value 14
Current Thread Thread -3 var value 15
Current Thread Thread -3 var value 16
Current Thread Thread -3 var value 17
Current Thread Thread -3 var value 18

同期とはそれ以上のものを意味します。それはメモリの障壁に大きな影響を与えます。
user1050755

1

単純同期とは、2つのスレッドがブロック/メソッドに同時にアクセスできないことを意味します。クラスのブロック/メソッドが同期されているとは、一度に1つのスレッドしかアクセスできないことを意味します。内部的には、最初にアクセスしようとするスレッドがそのオブジェクトをロックします。このロックが利用できない限り、他のスレッドはクラスのそのインスタンスの同期されたメソッド/ブロックにアクセスできません。

別のスレッドが、同期するように定義されていない同じオブジェクトのメソッドにアクセスできることに注意してください。スレッドは呼び出しによってロックを解放できます

Object.wait()

0

synchronizedJavaのブロックは、マルチスレッド化のモニターです。synchronized同じオブジェクト/クラスのブロックは単一のスレッドでのみ実行でき、他のすべてのスレッドは待機しています。race condition複数のスレッドが同じ変数を更新しようとする場合に役立ちます(最初のステップはvolatileAboutを使用しています)

Java 5synchronizedサポートについて拡張happens-before[概要]

モニターのアンロック(同期ブロックまたはメソッド出口)は、同じモニターの後続の各ロック(同期ブロックまたはメソッドエントリー)の前に発生します。

次のステップは java.util.concurrent

揮発性と同期


-6

synchronizedはJavaのキーワードであり、メモリの不整合とスレッドの干渉エラーを回避するために、マルチスレッド環境で関係の前に発生するために使用されます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.