2016-05-14 12 views
1

静的メソッド&非静的インスタンスメソッドを持つクラスが与えられた場合 どのような時点でこれらのメソッドの1つだけが呼び出されることを確認しますか?どのような時点で、クラスの静的メソッドと非静的メソッドのどちらか一方しか呼び出されないようにするにはどうすればよいですか?

例: ------

public class DoMath{ 


public static int getSum(){ 
//Sum 
} 

public int getSub(){ 
//Subtract 
} 

} 

今、あなたは、時間のいずれかの時点で、いずれか一方のみこれらのメソッドのが呼び出されることを確認する必要があります。

答えて

1

これはそれを行う必要があります。

public class DoMath{ 
    public static synchronized int getSum(){ 
     //Sum 
    } 

    public int getSub(){ 
     synchronized(DoMath.class) { 
      //Subtract 
     } 
    } 
} 

説明:暗黙的にメソッドを宣言したクラスのオブジェクトClassに同期しstatic synchronized方法。

+0

ただし、インスタンスメソッドでクラスレベルのロックを行うことはできますか? –

+0

はい。そしてそれが私の 'getSub'の実装がやっていることです。 –

1

プライベートロックホルダーを使用することをお勧めします。これにより、クラスの外側からコードをロックすることを防ぎます。これは以下の例で実証されています。パブリックにアクセス可能なクラスモニターが解放される前に、DoMathExposed#getSum()の出力の実行順序が戻ってくることに注意してください。一方、DoMathEncapsulated#getSum()はプライベートオブジェクトで同期されているのですぐに戻ります。したがって、パブリッククラスモニタを保持しても効果はありません。

import java.util.concurrent.CountDownLatch; 

public class DoMath { 

    public static void main(String[] args) throws InterruptedException { 

     System.out.println("\nTesting DoMathExposed.class\n"); 
     DoMathExposed.x = 3; 
     DoMathExposed.y = 4; 
     obtainMonitorOf(DoMathExposed.class); 
     System.out.println("Invoked DoMathExposed#getSum()"); 
     System.out.println("DoMathExposed#getSum() returned: " + DoMathExposed.getSum()); 

     System.out.println("\nTesting DoMathEncapsulated.class\n"); 
     DoMathEncapsulated.x = 1; 
     DoMathEncapsulated.y = 2; 
     obtainMonitorOf(DoMathEncapsulated.class); 
     System.out.println("Invoked DoMathEncapsulated#getSum()"); 
     System.out.println("DoMathEncapsulated#getSum() returned: " + DoMathEncapsulated.getSum()); 
    } 

    private static void obtainMonitorOf(final Class cls) throws InterruptedException { 
     final CountDownLatch latch = new CountDownLatch(1); 
     new Thread(new Runnable() { 
      @Override 
      public void run() { 
       synchronized(cls) { 
        System.out.println(cls.getName() + ".class MONITOR held for 10 seconds"); 
        latch.countDown(); 
        try { 
         Thread.sleep(10000); 
        } catch (InterruptedException e) { 
        } 
       } 
       System.out.println(cls.getName() + ".class MONITOR released"); 
      } 
     }).start(); 
     latch.await(); 
    } 
} 


class DoMathEncapsulated { 

    private static final Object lock = new Object(); 

    protected static int x; 
    protected static int y; 

    public static int getSum() { 
     synchronized(lock) { 
      return x + y; 
     } 
    } 

    public int getSub() { 
     synchronized(lock) { 
      return x - y; 
     } 
    } 
} 

class DoMathExposed { 

    protected static int x; 
    protected static int y; 

    public static synchronized int getSum() { 
     return x + y; 
    } 

    public int getSub() { 
     synchronized(DoMathExposed.class) { 
      return x - y; 
     } 
    } 
} 
+0

ロックオブジェクトの利点は何ですか? 私はクラスレベルのロックを使用して両方のメソッドを同期することをしようとしていると思いますか? –

+0

同期メソッドを使用するか、DoMathオブジェクト自体を同期させると、ロックホルダーが外部に公開されます。つまり、他の誰かがロックを取得してコードをブロックする可能性があります。プライベートロックホルダーの使用は、この場合DoMathオブジェクト内のロック動作をカプセル化するため、ベストプラクティスと見なされます。 – dimplex

+0

ロック・ホルダーを外の世界にさらしてしまった例を教えてください。小さな例やリソースは本当にそれを理解するのに役立ち、誰がそれが今/将来を探しているのかに有益でしょう。 –

関連する問題