2017-12-28 1 views
3

私はこのクラスを持っている:「クラスローディングデッドロック」とはどういう意味ですか?

public class User { 

    public static final NonRegisteredUser NON_REG_USER = new NonRegisteredUser(); 

    //... 

    public static class NonRegisteredUser extends User { 
     //... 
    } 

} 

とコードインスペクタには、この警告を検出された:クラスローディングのデッドロックにつながる可能性があるスーパーユーザー 初期化子から

参照サブクラスNonRegisteredUserを何

それはまさに意味ですか?

+0

私はそれが何を言っているかはかなり明らかだと思います。 'User'クラスの' NonRegisteredUser'を初期化します。 'User'クラスを読み込むたびに、' NON_REG_USER'が静的なので、永遠のループにつながります。 'NonRegisteredUser'が' User'などを拡張する原因となります。 –

+1

など、などに依存します。 JVMの実装はまったく初期化されないかもしれません。 – Antoniossss

+0

結局はあまり明確ではありませんでした。 –

答えて

5

あなたは2つのスレッドを持ち、もう1つはUserをロードするために開始し、もう1つはNonRegisteredUserをロードするために開始した場合、デッドロックにのみ発生する可能性があります。デッドロックを引き起こす同期が存在しますが、別のスレッドが必要です。ロードが単一のスレッドで行われる場合、スレッドが両方のロックを所有しているためデッドロックはありません。

メッセージのとなる可能性があります。しかし、デッドロックは通常、特定の環境を必要とする傾向があるので、それについては何も変わっていません。

+0

ありがとう。私はAndroidで作業していますので、場合によっては警告を解決する方がよいでしょう。 –

-1

クラスローダーの読み込み開始User

スタティックメンバーは、最初にin order or appearanceです。したがって、クラスローダーはNonRegisteredUserクラスを見て、その初期化のためにUserクラスをロードしようとします。

次に、クラスローダーはUserのロードを開始します。

スタティックメンバーは、最初にin order or appearanceです。したがって、クラスローダーはNonRegisteredUserクラスを見て、その初期化のためにUserクラスをロードしようとします。

次に、クラスローダーはUserのロードを開始します。

スタティックメンバーは、最初にin order or appearanceです。だから、クラスローダは... NonRegisteredUserクラスを見て、その初期化のためUserクラスをロードしようと

+2

ありがとうございます。だから、なぜそのコードは動作していますか?それは理にかなっていますか? –

+0

私が言ったことは100%正確ではないので、おそらく動作しているでしょう。コンパイラはクラスのための単一のinitプロセスを構築するので、JVMは実行時にそれを何度も盲目的に繰り返すことはありません。おそらく、この種の問題が修正された最適化がいくつかあります。 – Vaiden

+0

@Héctorそれは素晴らしい質問です。あなたが 'User.NON_REG_USER'属性を使うか、 'User.NonRegisteredUser'クラスを初期化しようとするとどうなりますか? –

関連する問題