ホームページ  >  記事  >  バックエンド開発  >  synchronized を使用してロック コードを実装する方法の詳細な説明

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

php中世界最好的语言
php中世界最好的语言オリジナル
2017-12-20 11:56:032478ブラウズ

この記事では、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 までご連絡ください。