【JUC】マルチスレッドロック

同期ロックの対象

Javaのすべてのオブジェクトは、ロックとして機能できます。これは、次の3つの形式で表されます。

  1. 通常の同期メソッドの場合、ロックは現在のインスタンスオブジェクトです。
  2. 静的同期メソッドの場合、ロックは現在のクラスバイトコードであるClassオブジェクトです。
  3. 同期されたメソッドブロックの場合、ロックは同期されたブラケットで構成されたオブジェクトです

公正および不公正なロック

不当なロック

 private final ReentrantLock lock = new ReentrantLock();
 // private final ReentrantLock lock = new ReentrantLock(false);

他のスレッドを飢えさせる可能性のある不公平なロック。(一人ですべての作業を行います。誰かがいるかどうかを尋ねるのではなく、つかむだけです)
高効率

フェアロック

private final ReentrantLock lock = new ReentrantLock(true);

太陽が輝いているので、誰かいるのか聞いてみると、行列ができます。
効率は比較的低いです。

リエントラントロック/再帰ロック

リエントラントロック機能のデモンストレーション:外側のロックを開いた後、内側のロックを開き続けることができます

public static void main(String[] args) {
    
    
        Object o = new Object();
        new Thread(()->{
    
    
            synchronized (o) {
    
    
                System.out.println(Thread.currentThread().getName() + "外层");
                synchronized (o) {
    
    
                    System.out.println(Thread.currentThread().getName() + "内层");
                }
            }
        },"AA").start();
}

再入可能ロックは、再帰呼び出しを繰り返すことができます

public class SyncLockDemo {
    
    

    public synchronized void add(){
    
    
        add();
    }
    
    public static void main(String[] args) {
    
    
        new SyncLockDemo().add();
    }
}

デッドロック

デッドロックとは:

リソースの競合により、2つ以上のプロセスが互いに待機します。外部干渉がない場合、プロセスは実行できなくなります。

デッドロックの原因

  1. 不十分なシステムリソース
  2. プロセス実行の事前注文は不適切です
  3. リソースの誤配分

デッドロックの例

public class DeadLock {
    
    

    //创建两个对象
    static Object a = new Object();
    static Object b = new Object();

    public static void main(String[] args) {
    
    
        new Thread(()->{
    
    
            synchronized (a) {
    
    
                System.out.println(Thread.currentThread().getName() + "持有锁a, 试图获取锁b");
                try {
    
    
                    TimeUnit.SECONDS.sleep(1);
                } catch (InterruptedException e) {
    
    
                    e.printStackTrace();
                }
                synchronized (b) {
    
    
                    System.out.println(Thread.currentThread().getName() + "获取到锁b");
                }
            }
        },"AA").start();

        new Thread(()->{
    
    
            synchronized (b) {
    
    
                System.out.println(Thread.currentThread().getName() + "持有锁b, 试图获取锁a");
                try {
    
    
                    TimeUnit.SECONDS.sleep(1);
                } catch (InterruptedException e) {
    
    
                    e.printStackTrace();
                }
                synchronized (a) {
    
    
                    System.out.println(Thread.currentThread().getName() + "获取到锁a");
                }
            }
        },"BB").start();
    }
}

デッドロックを確認します

  1. jps -lは、実行中のプログラムのプロセス番号を取得します
  2. jstackプロセス番号は、デッドロックが発生したかどうかを確認できます

おすすめ

転載: blog.csdn.net/weixin_44179010/article/details/123193167