ホームページ バックエンド開発 PHPチュートリアル synchronized を使用してロック コードを実装する方法の詳細な説明

synchronized を使用してロック コードを実装する方法の詳細な説明

Dec 20, 2017 am 11:56 AM
lock synchronized

この記事では、Synchronized を使用してロック コードを実装する方法を紹介します。以下は、必要な場合に参考にしてください。

方法 1:

public synchronized void a(){
  //TODO
}
ログイン後にコピー


方法 2:

public void b(){
  synchronized(this){
    //TODO
  }
}
ログイン後にコピー


これら 2 つの方法から、ロックがどのように行われるかを見てみましょう:

public void c() {
  lock.lock();
  try {
    // TODO
  } finally {
    lock.unlock();
  }
}
ログイン後にコピー


これ。 lock()とunlock()の間には一種のロックが追加されるため、ロック関数を実装したい場合は、lock()とunlock()の2つのメソッドをどのように実装するかを考える必要があります。まずフレームワークを定義します。 次のように:

public void lock(){
}
public void unlock(){
}
ログイン後にコピー


次に、synchronized を使用してこれら 2 つのメソッドを実装する方法を考えます。

これで、少し明確なアイデアが得られましたが、これら 2 つのメソッドをどのように入力するかはまだわかりません。後でロックの特性を分析してから、次のコードを見てみましょう。

このコードにいくつかのコメントを追加しただけで、他には何もしませんでした。このコードを理解し、最も頻繁に使用される単語 (currentthread) を確認してから、lock() メソッドと lock() メソッドを埋めてみましょう。 、解決策を見つけるためにキーワード currentthread を取得することに注意を払う必要がありますか?答えは「はい」です。

次に、同期を使用するときにスレッドを待機させる方法を分析します。 wait() メソッドを使用します。スレッドを起動するには、notify() メソッドを使用します。次に、lock() メソッドで wait() メソッドを使用し、unlock() メソッドで notify() メソッドを使用します。 wait()とnotify()を使用する場合には条件がありますが、その条件として何を使用するべきかを考えてください。


現在のロックが占有されているかどうかを判断条件として使用する必要があります。ロックが占有されている場合、synchronized を使用するときに常にこの条件を使用したかどうかを考えてみましょう。答えは「はい」です。

いつロックを解放するか、どのような条件が使用されるかを分析してみましょう。スレッド A がロックを取得した場合、スレッド B はそれを解放できますか?もちろんそうではありません。B が釈放された場合、それは原則に違反します。スレッド A のロックはスレッド A によってのみ解放できるはずです。したがって、判断条件は、ロックを保持しているスレッドが現在のスレッドであるかどうかを判断することです。そうでない場合は、もちろん解放できません。

それでは、完全なコードを見てみましょう:

public void c() {
    lock.lock();
    //When current thread get the lock, other thread has to wait
    try {
        //current thread get in the lock, other thread can not get in
        // TODO
    }
    finally {
        lock.unlock();
        //current thread release the lock
    }
}
ログイン後にコピー

それを実行して結果を確認してください:

package test.lock;
import java.util.Random;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
public class NaiveLock {
    private static final long NONE = -1;
    private long owner = NONE;
    private Boolean isLooked() {
        return owner != NONE;
    }
    public synchronized void lock() {
        long currentThreadId = Thread.currentThread().getId();
        if (owner == currentThreadId) {
            throw new IllegalStateException("Lock has been acquired by current thread");
        }
        while (this.isLooked()) {
            System.out.println(String.format("thread %s is waitting lock", currentThreadId));
            try {
                wait();
            }
            catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        owner = currentThreadId;
        System.out.println(String.format("Lock is acquired by thread %s", owner));
    }
    public synchronized void unlock() {
        if (!this.isLooked() || owner != Thread.currentThread().getId()) {
            throw new IllegalStateException("Only Lock owner can unlock the lock");
        }
        System.out.println(String.format("thread %s is unlocking", owner));
        System.out.println();
        owner = NONE;
        notify();
    }
    public static void main(String[] args) {
        final NaiveLock lock = new NaiveLock();
        ExecutorService executor = Executors.newFixedThreadPool(20, new ThreadFactory() {
            private ThreadGroup group = new ThreadGroup("test thread group");
            {
                group.setDaemon(true);
            }
            @Override
                  public Thread newThread(Runnable r) {
                return new Thread(group, r);
            }
        }
        );
        for (int i = 0; i < 20; i++) {
            executor.submit(new Runnable() {
                @Override
                        public void run() {
                    lock.lock();
                    System.out.println(String.format("thread %s is running...", Thread.currentThread().getId()));
                    try {
                        Thread.sleep(new Random().nextint(1000));
                    }
                    catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    lock.unlock();
                }
            }
            );
        }
    }
}
ログイン後にコピー


forループ

を30回に変更すると、結果が表示されますもう一度:

Lock is acquired by thread 8
thread 8 is running...
thread 27 is waitting lock
thread 26 is waitting lock
thread 25 is waitting lock
thread 24 is waitting lock
thread 23 is waitting lock
thread 22 is waitting lock
thread 21 is waitting lock
thread 20 is waitting lock
thread 19 is waitting lock
thread 18 is waitting lock
thread 17 is waitting lock
thread 16 is waitting lock
thread 15 is waitting lock
thread 14 is waitting lock
thread 13 is waitting lock
thread 12 is waitting lock
thread 11 is waitting lock
thread 10 is waitting lock
thread 9 is waitting lock
thread 8 is unlocking
  
Lock is acquired by thread 27
thread 27 is running...
thread 27 is unlocking
  
Lock is acquired by thread 26
thread 26 is running...
thread 26 is unlocking
  
Lock is acquired by thread 25
thread 25 is running...
thread 25 is unlocking
  
Lock is acquired by thread 24
thread 24 is running...
thread 24 is unlocking
  
Lock is acquired by thread 23
thread 23 is running...
thread 23 is unlocking
  
Lock is acquired by thread 22
thread 22 is running...
thread 22 is unlocking
  
Lock is acquired by thread 21
thread 21 is running...
thread 21 is unlocking
  
Lock is acquired by thread 20
thread 20 is running...
thread 20 is unlocking
  
Lock is acquired by thread 19
thread 19 is running...
thread 19 is unlocking
  
Lock is acquired by thread 18
thread 18 is running...
thread 18 is unlocking
  
Lock is acquired by thread 17
thread 17 is running...
thread 17 is unlocking
  
Lock is acquired by thread 16
thread 16 is running...
thread 16 is unlocking
  
Lock is acquired by thread 15
thread 15 is running...
thread 15 is unlocking
  
Lock is acquired by thread 14
thread 14 is running...
thread 14 is unlocking
  
Lock is acquired by thread 13
thread 13 is running...
thread 13 is unlocking
  
Lock is acquired by thread 12
thread 12 is running...
thread 12 is unlocking
  
Lock is acquired by thread 11
thread 11 is running...
thread 11 is unlocking
  
Lock is acquired by thread 10
thread 10 is running...
thread 10 is unlocking
  
Lock is acquired by thread 9
thread 9 is running...
thread 9 is unlocking
ログイン後にコピー

これらの事例を読んだ後、あなたはその方法を習得したと思います。さらに興味深い情報については、php 中国語 Web サイトの他の関連記事に注目してください。

関連書籍:


PHP がスタック データ構造とブラケット マッチング アルゴリズムを実装する方法の詳細なコード例

PHP の最も単純な文字列マッチング アルゴリズム、PHP マッチング アルゴリズム_PHP チュートリアル

最も単純な文字列マッチング アルゴリズムのチュートリアルphp で

以上がsynchronized を使用してロック コードを実装する方法の詳細な説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

JavaマルチスレッドでLockを使用する方法 JavaマルチスレッドでLockを使用する方法 May 12, 2023 pm 02:46 PM

Jdk1.5 以降では、java.util.concurrent.locks パッケージの下に、スレッド同期用のインターフェイスとクラスのセットが存在します。スレッド同期に関して言えば、組み込みキーワードである synchronized キーワードを誰もが思い浮かべるかもしれません。 Java ではスレッドの同期を処理しますが、このキーワードには多くの欠陥があり、利便性や直感的に使用することが難しいため、Lock が表示されます。通常、synchronized キーワードを使用すると、次の問題が発生します。 (1) 制御不能、自由にロックしたりロックを解放したりできない。 (2) 効率は比較的低く、たとえば、現在 2 つのファイルを同時に読み取っています。

Java での Synchronized の原理と使用シナリオ、および Callable インターフェイスの使用法と差異分析 Java での Synchronized の原理と使用シナリオ、および Callable インターフェイスの使用法と差異分析 Apr 21, 2023 am 08:04 AM

1. 基本機能 1. 楽観的ロックで開始し、ロック競合が多発する場合は悲観的ロックに変換する 2. 軽量なロック実装で開始し、長時間ロックを保持するとロックを解除する3. 軽量ロックを実装するときに最もよく使用されるスピン ロック戦略 4. 不公平なロックである 5. リエントラント ロックである 6. 読み取り/書き込みロックではない 2. JVMロック プロセスを同期します。 ロックは、ロックなし、バイアスされたロック、軽量ロック、および重量ロックの状態に分類されます。状況に応じて順次バージョンアップしていきます。偏ったロックは男主人公を鍵、女主人公をスレとするもので、このスレッドだけがこのロックを使用すれば、たとえ結婚証明書を取得しなくても男主人公と女主人公は永遠に幸せに暮らせる(高額回避) -コストオペレーション)しかし、女性のサポート役が登場します

JavaでLockを使用するにはどのような方法がありますか? JavaでLockを使用するにはどのような方法がありますか? Apr 23, 2023 pm 08:52 PM

1. 機能 (1) ロックを取得する Lock メソッドは、割り込みをサポートし、タイムアウト後の取得なし、ノンブロッキング (2) セマンティクスを改善します。どこでロックおよびロックを解除するかを書き出す必要があります (3) ロックの明示的なロックにより、次のことが可能になります。優れた柔軟性を備えていますが、同時にロックを手動で解放する必要があります (4) サポート条件条件オブジェクト (5) 複数の読み取りスレッドが同時に共有リソースにアクセスできるようにします 2. ロックの使用法 // ロックを取得 voidlock() //現在のスレッドがロックを取得していない場合、中断された場合、ロックを取得します voidlockInterruptibly()//この Lock インスタンスにバインドされた新しい Condition インスタンスを返します ConditionnewCondition()//呼び出されたときのみロックします

Java Lock クラスはどのような機能を提供しますか? Java Lock クラスはどのような機能を提供しますか? Apr 21, 2023 am 08:16 AM

注1. Lockはjava.util.concurentパッケージ配下のインタフェースであり、一連のロック操作メソッドを定義しています。 2. Lock インターフェイスには、主に ReentrantLock、ReentrantReadWriteLock、ReentrantReadWriteLock、および WriteLock 実装クラスが含まれます。 Synchronized とは異なり、Lock はロックの取得やロックの解放などの関連インターフェイスを提供するため、より柔軟に使用でき、より複雑な操作が可能になります。 InstanceReentrantReadWriteLocklock=newReentrantReadWriteLock();Lockread

Javaキーワード同期原理とロック状態の分析例 Javaキーワード同期原理とロック状態の分析例 May 11, 2023 pm 03:25 PM

1. Java におけるロックの概念 Spin ロック: スレッドがロックを取得するとき、そのロックが別のスレッドによって取得されている場合、スレッドはループで待機し、ロックが正常に取得できるかどうかを判断し続けます。ロックが取得されると、ロックはループを終了します。楽観的ロック: 競合がないことを前提として、データを変更する際に以前に取得したデータと不整合が見つかった場合、最新のデータを読み込み、変更を再試行します。悲観的ロック: 同時実行性の競合が発生することを想定し、すべてのデータ関連操作を同期し、データが読み取られた時点からロックを開始します。排他的ロック (書き込み): リソースに書き込みロックを追加します。スレッドはリソースを変更できますが、他のスレッドはリソースを再度ロックすることはできません (単一書き込み)。共有ロック (読み取り): リソースに読み取りロックを追加した後、読み取りのみ可能ですが変更はできません。他のスレッドは読み取りロックのみを追加でき、書き込みロック (複数) を追加できません。 S として参照

synchronized を使用して Java で同期メカニズムを実装するにはどうすればよいですか? synchronized を使用して Java で同期メカニズムを実装するにはどうすればよいですか? Apr 22, 2023 pm 02:46 PM

Java 1 での synchronized の使い方のまとめ。関数修飾子として synchronized を使用した場合のサンプルコードは次のようになります: Publicsynchronizedvoidmethod(){//….} これが同期メソッドですが、このときどのオブジェクトが同期ロックされているのでしょうか?彼がロックするのは、この同期されたメソッド オブジェクトを呼び出すことです。言い換えれば、オブジェクト P1 がこの同期メソッドを異なるスレッドで実行すると、同期効果を達成するために相互排他が形成されます。ただし、このオブジェクトが属するクラスが生成する別のオブジェクトP2は、synchronizedキーワードを付加してこのメ​​ソッドを任意に呼び出すことができる。上記のサンプルコードなど。

Java の 3 つの同期方法とその使用方法は何ですか? Java の 3 つの同期方法とその使用方法は何ですか? Apr 27, 2023 am 09:34 AM

1. 同期は最も一般的に使用される同期方法であり、これには主に 3 つの使用方法があることを説明します。 2. 例//一般的なクラス メソッドの同期 synchronizedpublidvoidinvoke(){}//クラスの静的メソッドの同期 synchronizedpublicstaticvoidinvoke(){}//コード ブロックの同期 synchronized(object){}これら 3 つのメソッドの違いは、同期されるオブジェクトが異なることです。通常のクラスはオブジェクト自体を同期し、静的メソッドはクラス自体を同期し、コード ブロックは括弧内のオブジェクトを同期します。 Javaにはどのようなコレクションがありますか?

Java 同期ロックのアップグレードの原理とプロセスは何ですか? Java 同期ロックのアップグレードの原理とプロセスは何ですか? Apr 19, 2023 pm 10:22 PM

ツールの準備 同期の原理について正式に説明する前に、まずスピン ロックについて話しましょう。スピン ロックは同期の最適化に大きな役割を果たすためです。スピン ロックを理解するには、まずアトミック性とは何かを理解する必要があります。いわゆるアトミック性とは、単に各操作が行われないか完了することを意味します。すべてを行うということは、操作中に中断できないことを意味します。たとえば、変数データに 1 を追加するには、次の 3 つのステップがあります: メモリからレジスタにロードする。データの値に 1 を加算します。結果をメモリに書き込みます。原子性とは、スレッドがインクリメント操作を実行しているときに、他のスレッドによって中断できないことを意味し、このスレッドがこれら 3 つのプロセスを完了した場合にのみ実行されます。

See all articles