JAvaスレッドセキュリティ編synchronized複数スレッド複数ロック(二)


科学技術の速報
      北京時間15日夜、CNBCによると、マイクロソフトの創業者ビル・ゲイツ氏は、技術が貧富の格差を激化させる可能性があると述べた.技術の進歩がもたらすメリットは、誰もが享受できるものではないかもしれません.      彼はサウジアラビアで開かれたミスクグローバルフォーラム(Misk Global Forum)で、「私たちがうっかりすると、技術は金持ちと貧乏人の差を激化させる.技術が高価な学校でしか教授されていないと、一人一人に恩恵を与えることができないからだ」と話した.      この億万長者はまた、人工知能(AI)の懸念についても言及し、人工知能(AI)のような科学技術の進歩がもたらすメリットは、潜在的な罠を超えていると述べた.「私たちは不足している世界にあり、これらの進歩は私たちがすべての最も重要な問題を解決するのに役立つだろう」と述べた.      数日前、有名な物理学者スティーブン・ホーキングはAIの出現に対して「人類文明史上最悪の事件」かもしれないと警告し、社会がその発展をコントロールする方法を見つけない限り.
複数スレッド複数ロック
迅速な理解
      複数のスレッドで、各スレッドが自分で指定したロックを取得し、それぞれロックを取得した後、synchronizedメソッドボディの内容を実行します.
ケース

package cn.hfbin.base.sync002;
/**
 * @author cn.hfbin
 *
 */
public class MultiThread {

    private int num = -1;

    /** static */
    public synchronized void printNum(String tag){
        try {

            if(tag.equals("a")){
                num = 1;
                System.out.println("Thread m1");
                Thread.sleep(1000);
            } else {
                num = 2;
                System.out.println("Thread m2");
            }

            System.out.println("Thread " + tag + ", num = " + num);

        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    //    run      
    public static void main(String[] args) {

        //       
        final MultiThread m1 = new MultiThread();
        final MultiThread m2 = new MultiThread();

        Thread t1 = new Thread(new Runnable() {
            @Override
            public void run() {
                m1.printNum("a");
            }
        });

        Thread t2 = new Thread(new Runnable() {
            @Override 
            public void run() {
                m2.printNum("b");
            }
        });     

        t1.start();
        t2.start();

    }
}

印刷結果:
Thread m1
Thread m2
Thread b, num = 2
Thread a, num = 1

私たちの正常な思考に基づいて印刷された結果は
Thread m1
Thread a, num = 1
Thread m2
Thread b, num = 2

このように、キーワードsynchronizedが取得したロックはいずれもオブジェクトロックであり、互いに影響を及ぼさず、m 1とm 2の情報はすべて自分のスレッドスタックに保存され、他のスレッドには見えず、t 1とt 2が同時に実行されることを示す.
printNumメソッドにstaticキーを付けると、その印刷結果はどうなりますか.次のようなケースがあります.
public class MultiThread {

    private static int num = -1;

    /**
     * static
     */
    public static synchronized void printNum(String tag) {
        try {

            if (tag.equals("a")) {
                num = 1;
                System.out.println("Thread m1");
                Thread.sleep(1000);
            } else {
                num = 2;
                System.out.println("Thread m2");
            }

            System.out.println("Thread " + tag + ", num = " + num);

        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    //    run      
    public static void main(String[] args) {

        //       
        final MultiThread m1 = new MultiThread();
        final MultiThread m2 = new MultiThread();

        Thread t1 = new Thread(new Runnable() {
            @Override
            public void run() {
                m1.printNum("a");
            }
        });

        Thread t2 = new Thread(new Runnable() {
            @Override
            public void run() {
                m2.printNum("b");
            }
        });

        t1.start();
        t2.start();

    }
}

印刷結果
Thread m1
Thread a, num = 1
Thread m2
Thread b, num = 2

staticを付けた後に結果を印刷するのが私たちが予想した結果で、printNumメソッドにstaticキーワードを付けてclassクラスをロックすることを示します.複数のMultiThreadリファレンスが宣言されてもprintNumメソッドはクラスに従ってスタックに格納され、スレッド間でリソースが共有され、出力結果はm 1情報の出力が終了するまでm 2情報の出力が開始されません.
ケーススタディ
キーワードsynchronizedが取得したロックはすべてオブジェクトロックであり、一部のコード(メソッド)をロックとするのではないので、サンプルコードではそのスレッドがsynchronizedキーワードを先に実行する方法であり、そのスレッドはそのメソッドが属するオブジェクトのロック(Lock)を持っており、2つのオブジェクト、スレッドが取得したのは2つの異なるロックであり、彼らは互いに影響しない.静的メソッドにsynchronizedキーワードを付けて.classクラスをロックし、クラスレベルのロック(独占.classクラス)を表す場合があります.
ソース:https://github.com/hfbin/Thread_Socket/tree/master/Thread/sync002