【Javaマルチスレッド】スレッドの安全性の問題を解決するLockロック方法

ロック(ロック)

1. JDK 5.0以降Java はより強力なスレッド同期メカニズムを提供します。同期は、同期ロック オブジェクトを明示的に定義することによって実現されます。同期ロックは、Lockオブジェクトを使用して実装されます。

2. java.util.concurrent.locks.Lock インターフェースは、複数のスレッドによる共有リソースへのアクセスを制御するためのツールですロックは、共有リソースへの排他的アクセスを提供します。一度に 1 つのスレッドのみがLockオブジェクトをロックでき、スレッドは共有リソースへのアクセスを開始する前にLockオブジェクトを取得する必要があります。

3. ReentrantLockクラスはsynchronized と同じ同時実行性とメモリ セマンティクスを備えたLockを実装します。スレッド セーフな制御を実装する場合、明示的にロックとロックを解放できるReentrantLockがより一般的に使用されます

================================================= =======================

質問:チケットを販売する窓口を 3 つ作成し、合計 100 枚のチケットを販売します。例として

未解決のスレッド セーフティの問題があるコード:

class Window implements Runnable {

    private int ticket = 100;

    @Override
    public void run() {
        while (true) {
            if (ticket > 0) {
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName() + ":售票,票号为:" + ticket);
                ticket--;
            } else {
                break;
            }
        }
    }
}

public class LockTest {
    public static void main(String[] args) {
        Window w = new Window();

        Thread t1 = new Thread(w);
        Thread t2 = new Thread(w);
        Thread t3 = new Thread(w);

        t1.setName("窗口1");
        t2.setName("窗口2");
        t3.setName("窗口3");

        t1.start();
        t2.start();
        t3.start();
    }

}

上記のコードでは、大量の投票や誤った投票が発生します。

次に、Lock lock メソッドを通じてスレッドの安全性の問題を解決します。

ロック(ロック)

class A{
        private final ReentrantLock lock = new ReenTrantLock();
        public void m(){

            lock.lock();

            try{
                //保证线程安全的代码;
            }

            finally{

                lock.unlock();

            }
        }
    }

Lock ロック メソッドを使用してスレッド セーフティの問題を解決した後のコードは次のとおりです。

class Window implements Runnable {

    private int ticket = 100;

    //1.实例化ReentrantLock
    private ReentrantLock lock = new ReentrantLock();

    @Override
    public void run() {
        while (true) {
            try {

                //2.调用锁定方法lock()
                lock.lock();
                if (ticket > 0) {
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread().getName() + ":售票,票号为:" + ticket);
                    ticket--;
                } else {
                    break;
                }
            }finally {
                //3.调用解锁方法:unlock()
                lock.unlock();
            }
        }
    }
}

public class LockTest {
    public static void main(String[] args) {
        Window w = new Window();

        Thread t1 = new Thread(w);
        Thread t2 = new Thread(w);
        Thread t3 = new Thread(w);

        t1.setName("窗口1");
        t2.setName("窗口2");
        t3.setName("窗口3");

        t1.start();
        t2.start();
        t3.start();
    }

}

================================================= == ===========================
同期 vs ロック

1. ロックは明示的ロック (手動でロックを開閉し、ロックを閉じることを忘れないでください)、同期は暗黙的ロックであり、範囲外になると自動的に解放されます。

2. ロックにはコード ブロック ロックのみがあり、同期にはコード ブロック ロックとメソッド ロックがあります。

3. Lock ロックを使用すると、JVM はスレッドのスケジュールに費やす時間が短縮され、パフォーマンスが向上します。拡張性が優れています (より多くのサブクラスを提供します)

優先順位:

ロック -> 同期コード ブロック (メソッド本体に入り、対応するリソースが割り当てられている) -> 同期メソッド (メソッド本体の外)

見てくれてありがとう!

おすすめ

転載: blog.csdn.net/qq_64976935/article/details/128893834