2017-11-10 23 views
3

私のプロジェクトの一部をjavaからkotlinに変換しようとしています。 1つはシングルトンマネージャクラスです。 Javaクラスは次のようになりますkotlinのlateinit、lazy、singletonパターン

public class Manager { 
    private static volatile Manager Instance = null; 
    private static final Object InstanceLock = new Object(); 
    private Manager(Object1 object1, Object2 object2, Object3 object3){//...}; 
    public static boolean isInitialized(){ 
    synchronized(InstanceLock){ 
     return Instance == null; 
    } 
    } 
    public static void initialize(Object1 object1, Object2 object2, Object3 object3){ 
     if(Instance == null){ 
     synchronized(InstanceLock){ 
      if(Instance == null){Instance = new Manager(object1, object2, object3}; 
     } 
     } 
    } 
    public static getInstance(){ 
     Precondition.checkNotNull(Instance, msg...); 
     return Instance; 
    } 
} 

また、私は逆コンパイルしてjavaに戻します。コンパニオンクラスでは、次のコードを取得します。

public static final class Companion { 
    @Nullable 
    public final Manager getInstance() { 
    return Manager.instance; 
    } 

    private final void setInstance(Manager var1) { 
    Manager.instance = var1; 
    } 

    private final Object getInstanceLock() { 
    return Manager.InstanceLock; 
    } 

    public final boolean isInitialized() { 
    Object var1 = Manager.Companion.getInstanceLock(); 
    synchronized(var1){} 

    boolean var4; 
    try { 
     var4 = Manager.Companion.getInstance() == null; 
    } finally { 
     ; 
    } 

    return var4; 
    } 

    public final void initialize(@NotNull String string1, @NotNull String string2) { 
    Intrinsics.checkParameterIsNotNull(string1, "string1"); 
    Intrinsics.checkParameterIsNotNull(string2, "string2"); 
    if (((Manager.Companion)this).getInstance() == null) { 
     Object var3 = ((Manager.Companion)this).getInstanceLock(); 
     synchronized(var3){} 

     try { 
      if (Manager.Companion.getInstance() == null) { 
       Manager.Companion.setInstance(new Manager(string1, string2, (DefaultConstructorMarker)null)); 
      } 

      Unit var5 = Unit.INSTANCE; 
     } finally { 
      ; 
     } 
    } 

    } 

    private Companion() { 
    } 

    // $FF: synthetic method 
    public Companion(DefaultConstructorMarker $constructor_marker) { 
    this(); 
    } 

}

1)どのように私はkotlinコンパニオンオブジェクト内lateinitや怠惰を使用して、スレッドの安全性、シングルトンを達成していますか?私が見ることができるように、逆コンパイルされたJavaコードは、初期化関数では同期呼び出しを持ちますが、同期本体では何もありません。

2)私はkotlin object/lazyにスレッドセーフの保証が付いていると思いますが、ダブルチェックのロックパターンでどのように活用できますか?

3)ダブルチェックロックパターンよりも良いパターンはありますか?コンストラクタに引数が必要であると仮定します。

4)私はこのマネージャークラスをできるだけ小さくkotlinファイルに変換することに影響を与えようとしています(このマネージャーファイルは他のJavaコードとも動作するはずです)。私は@Jvmstaticまたは@Jvmfieldをいくつかの他の変数やコンパニオンオブジェクト内の関数に追加しなければならないことに注意してください。マネージャの静的フィールドを呼び出す他のjavaファイルを更新する必要はありません。

5)このマネージャが現在純粋なkotlin環境で作業している場合、複数の引数を持つシングルトンクラスを実装するベストプラクティスは何でしょうか?

答えて

0

私はすべての質問に答えがありませんが、Kotlinでシングルトンクラスを作成するための定義された方法があります。

classの接頭辞の代わりに、objectを使用してください。例えば

object Manager { 
    // your implementation 
} 

これ、このクラスのシングルトンを作り、あなたは直接Manager.getInstance()のように、Javaからこれを使用することができます(私は正確な構文を覚えていなかったが、これは動作するはずです)。 Kotlinはあなたのためにそれを作成します。

thisを参照してください。

少しお手伝い願います。

1

最初の回答は同期には対応していませんが、btwは依然として認識されている複雑さです。周りにはまだ二重チェックロックをしていると言っているトンの人々があります。しかし、DCLが必ずしも機能するとは限らないことを示すかなり説得力のある議論がいくつかあります。

興味深いことに、私は最近この同じ問題があり、this articleが見つかりました。私はそれを発見し、この最初の時間を好きではなかったが、私はそれを数回再訪しているため、大部分で、それまで温め:

  • は、著者が行って、Kotlin STDLIB
  • からコードを得ましたその結果、主要な問題はすべて、この治療にブローチ加工されていることを

お知らせかなり説得力のある醜いもたらすの種類を再利用しながら、パラメータ化メカニズム、次のとおりです。

  • 同期は
  • 私はこれはかなりこの上の最初と最後の言葉だと思う複雑な初期化
  • (コンテキスト神オブジェクトがineradicableであるAndroidの、で非常に重要な)パラメータ化された初期コンパイルされたコード要するに

を結果

  • トピック、驚くほど、ミディアムに見つかりました。

  • 関連する問題