synchronizedの面接問題について


面接の過程で、私たちはよくマルチスレッドの問題を考察されます.マルチスレッドは使いやすいが、不適切な使用は多くの同時問題をもたらす.スレッドの安全をどのように保証するかは自然に避けられない話題だ.
最近、会社は賢納士を募集して、面接の過程で、私はすべての人がキーワードsynchronizedがスレッドの同期に使われていることを知っていて、スレッドの安全を保証していることを発見しました.しかし、これ以上深く話をすると、気まずい状況に陥りやすい.私も「話題を変えて」とか「今日はここまで」と遠慮するしかありませんが...(PS:13を装いすぎませんか?履歴書は5+の仕事経験が多いです)
2020年は平凡ではない年に決まっている.疫病の間、面接の機会は特に重要だ.だからわざわざ時間を割いてこの文章を書いて、面接者一人一人が好きな仕事を見つけるのを助けたいと思っています.
1.synchronizedの概要
synchronizedは、ロックではなくロックとして理解する必要があります.この思考は、スレッドの同期をよりよく理解するのに役立ちます.
1.1 synchronizedの使用およびそれぞれのロックオブジェクト
ここで簡単に紹介して、今後の内容のために敷物を作ります.
  • 一般的な方法:施錠対象はthis、いわゆる方法錠(本質的に対象錠に属する)
  • public synchronized void say(){
         
    	 System.out.println("Hello,everyone...");
    }
    
  • 同期コードブロック(方法中):ロック対象はsynchronized(obj)の対象、いわゆる対象ロック
  •  public  void say(boolean isYou){
         
            synchronized (obj){
         
                System.out.println("Hello");
            }
        }
    
  • 同期静的方法:ロック対象が現在のクラスのClass対象である(XXX.class)、いわゆるクラスロック
  •  public static synchronized void work(){
         
            System.out.println("Work hard...");
        }
    

    时には面接官が问题の说明をはっきりしない时、勇敢に直ちに面接官と疎通しなければならない.就職活動では奇抜な面接官に出会うことがありますが、遭遇する確率が高すぎる場合は、自覚的に自分を見つめてみてください...
    1.2 synchronizedのコードブロックに関する疑問
    上のsynchronizedの使い方を見て、あなたはこのような疑問を持っていますか?synchronizedはクラスレベル(静的)コードブロックを修飾できますか?(PS:この話題は私が思いついたので、また面接で効果を聞いてみましょう...)
    結論:synchronizedはクラスレベルの(静的)コードブロックでは使用できません
    面接でコンパイラをあげなければ、多くの人がmountain泰を望んでいるのではないでしょうか.ここで私の理解を直接示します.
    これはロード順から考える.クラスレベルのコードブロックは、ロード順序で任意のメソッドよりも優先され、その実行順序はコード位置の前後にのみ関係します.誰もあなたと争っていないので、同期する必要はありません.
    2.synchronizedに関する面接問題
    ここでは、synchronizedキーワードを考察し、テーマに直行してDCL(Double Check Lock)の二重チェックロックの一例に入ることを主な内容とする一般的な面接問題-単例モードで展開します.
    2.1 DCLをめぐる話題
    2.1.1 DCLを実現
    この一歩が通れないと、気まずい思いをしてしまいます...
    public class SingleInstance {
         
        private volatile static SingleInstance instance = null;
        private SingleInstance(){
          }
        public static SingleInstance getInstance(){
         
            if (instance == null){
         
                synchronized (SingleInstance.class){
         
                    if (instance == null){
         
                        instance = new SingleInstance();
                    }
                }
            }
            return instance;
        }
    }
    

    2.1.2 synchronizedの役割について
    synchronizedキーワードは、主に、修飾されたコードが任意の時点で1つのスレッドのみで実行されることを保証するマルチスレッド同期問題を解決するために使用される.场合によっては、その使い方や実装原理(moniterenterとmoniterexit命令を使用している...)を话すと、PS:synchronizedの実装原理が単独で展开されます...
    2.1.3ここ(DCL)のvolatileの役割
    volatileは変数の可視性のみを保証し,volatile修飾変数の動作の原子性を保証することはできない.
    volatileの主な役割:
  • メモリの可視性を保つ;すべてのスレッドに共有メモリの最新状態が表示されます.
  • 指令再配置の問題を防止する.

  • メモリバリアを設定することで実現します.興味のある方はJava仮想マシンを深く理解してみてください
    个人的には拙见で、上记の内容を答えればいいのですが、もっと深いのはSHOWか圧给か...
    2.2基礎面接ポイント
    視聴者の時間を節約するために、まず結論を出します.
  • オブジェクトロックであれば、各オブジェクトは独自のユニークなロックを持ち、オブジェクト間のロックは互いに影響しない.クラスロックの場合、クラスのすべてのオブジェクトがこのロックを共有します.
  • 1つのスレッドがロックを取得し、ロックを取得していないスレッドはキューに並んで待つしかない.
  • synchronizedは再入錠可能であり、多くの場合のデッドロックの発生を避ける.
  • synchronizedメソッドに異常が発生した場合、JVMは自動的にロックを解除します.
  • ロック対象を空にしないでNPE(NullPointerException)を放出する
  • 同期自体は継承性を備えていない:すなわち親のsynchronizedメソッドであり、子クラスはこのメソッドを書き換え、状況別検討:synchonized修飾がなければ、この子メソッドはスレッド同期ではない.(PS:同期継承性に関する問題は状況別)
  • synchronized自体の修飾範囲が小さいほど良い.結局、同期ブロックです.走るのが速くないのに追い越し車線を占めている・
  • 2.2.1 synchronizedの静的および非静的メソッドに同時にアクセスし、スレッドの安全を保証できますか?
    結論:いいえ、両者のロック対象は違います.前者はクラスロック(XXX.class)、後者はthis
    2.2.2 synchronizedメソッドと非同期メソッドを同時にアクセスし、スレッドの安全を保証できますか?
    結論:いいえ、synchronizedは修飾された方法にしか役に立たないからです.
    2.2.3 2つのスレッドが同時に2つのオブジェクトにアクセスする非静的同期方法は、スレッドの安全を保証しますか?
    結論:いいえ、オブジェクトごとにロックがあります.2つのオブジェクトは2つのロックに相当し、ロックオブジェクトが一致しない.(PS:クラスロックの場合、すべてのオブジェクトが1つのロックを共有する)
    2.2.4 synchronizedメソッドが異常を投げ出すと、デッドロックになりますか?
    JVMは自動的にロックを解除し、デッドロックの問題は発生しない
    2.2.5 synchronizedのロックオブジェクトを空にできますか?どうなるの?
    ロックオブジェクトを空にすることはできません.そうしないとNPE(NullPointerException)が放出されます.
    2.2.6 synchronizedのロックオブジェクトを空にできますか?どうなるの?
    ロックオブジェクトを空にすることはできません.そうしないとNPE(NullPointerException)が放出されます.
    2.3継承性に関する面接ポイント
    2.3.1 synchronizedに関する継承性の問題
    親クラスのsynchronizedを書き換える方法は、主に2つのケースに分けられます.
  • サブクラスのメソッドはsynchronizedで修飾されていない:
  • synchronizedの継承性はありません.サブクラスメソッドはスレッドが安全ではありません.
  • サブクラスのメソッドがsynchronizedによって修飾されている(ここでは主にロック対象の帰属問題を考察する):
  • 2つのロックオブジェクトは、実はロックであり、サブクラスオブジェクトがロックとして機能します.これもsynchronizedのロックが再入可能であることを証明した.デッドロックの問題が発生します.
    2.4実戦経験の面接ポイント
    2.4.1開発中、synchronizedメソッドを多く使用しますか?それともsynchronizedコードブロックをよく使用しますか?and why?
    synchronizedの内容部分については、面接の過程でよく聞いて、この問題だけを聞きました.これは面接者の総合的な素質をよく考察できると思います.(PS:さすがにネジを締めます…)
    synchronized同期の範囲は小さいほどよい.この方法に時間がかかる場合、他のスレッドはロックスレッドが実行されるまで待たなければならないからです.(黄花菜は冷めても...)synchronizedコードブロック部分はこの部分だけが同期しており、他のものは非同期で実行でき、実行効率が向上します.
    2.4.2デッドロックの例を書いてください
    私には物語がありますが、お酒はありますか.
    public class DeadLock {
         
        String story = "  ";
        String wine = " ";
    
        public  void wantWine() throws InterruptedException {
         
            synchronized (story){
         
                System.out.println("    :"+ story +"  :"+ wine);
                Thread.sleep(1000);
                synchronized (wine){
         
                    System.out.println("  :"+ wine);
                }
            }
        }
    
        public void wantStory() throws InterruptedException {
         
            synchronized (wine){
         
                System.out.println("    :"+ wine +"  :"+ story);
                Thread.sleep(1000);
                synchronized (story){
         
                    System.out.println("  :"+ story);
                }
            }
        }
    
        public static void main(String[] args) {
         
            DeadLock deadLock = new DeadLock();
    
            new Thread(new Runnable() {
         
                @Override
                public void run() {
         
                    try {
         
                        deadLock.wantWine();
                    } catch (InterruptedException e) {
         
                        e.printStackTrace();
                    }
                }
            }).start();
    
            new Thread(new Runnable() {
         
                @Override
                public void run() {
         
                    try {
         
                        deadLock.wantStory();
                    } catch (InterruptedException e) {
         
                        e.printStackTrace();
                    }
                }
            }).start();
    
        }
    }
    
    

    2.4.2 synchronizedが無効になった問題はありますか?
    このような質問に対しては,面接者の実際の開発における経験が豊富であるかどうかを考察することが主であり,正直に答えることができる.
    synchronizedは使い方は簡単ですが、ロックオブジェクトが一致しないと失効します.問題を調べるときは、鍵の対象が一致しているかどうかを判断することに重点を置かなければならない.
    注意深い読者は発見することができて、浄XC、意外にもsynchronizedの原理に対して分析していないで、およびJDK 1.6時、Java公式はsynchronizedを最適化しても言及しなかった.焦らないで、後で補充して...