2017-03-19 8 views
2

Objectクラスのwait、notify、およびnotifyAllメソッドが呼び出されて返されるたびに、コンソールに出力しようとしています。これを実現するために、ロックオブジェクトに代わってwait、notifyおよびnotifyAllメソッドを呼び出すラッパークラスを作成しました。その後、wait、notify、notifyAllの代わりにラッパーのメソッドを使用します。ここでは、この時私の最高の試み、一つはRunnableをR1wait()とnotify()メソッドをログに記録するより良い方法を探しています

Runnable r1 = new Runnable() { 
    @Override 
    public void run() { 
     synchronized (lock) { 
      try { 
       // wait not wrapped in while loop for brevity. 
       //lock.wait(); 
       lock.objWrapper.waitNew(); // Use the wrapper method instead of wait() 
      } catch (InterruptedException e) {} 
     } 
    } 
}; 

スレッド二つの実験のRunnable R2

Runnable r2 = new Runnable() { 
    @Override 
    public void run() { 
     synchronized(lock) { 
      //lock.notifyAll(); 
      lock.objWrapper.notifyAllNew(); // Use the wrapper method instead of notifyAll() 
     } 
    } 
}; 

クラスロックが

public class Lock { 
    ObjWrapper objWrapper = new ObjWrapper(this); 
    // shared data here 
} 

Lock lock = new Lock(); 

、として定義されているが実行されます

スレッドですラッパークラスは、

public class ObjWrapper { 
    Object obj = null; 

    ObjWrapper(Object obj) { 
     System.out.println("New Object wrapper created: Thread: " + Thread.currentThread() + " at time: " + Instant.now()); 
     this.obj = obj; 
    } 

    public void waitNew() throws InterruptedException { 
     System.out.println("Entering Object::wait: Thread: " + Thread.currentThread() + " at time: " + Instant.now()); 
     obj.wait(); 
     System.out.println("Exiting Object::wait: Thread: " + Thread.currentThread() + " at time: " + Instant.now()); 
    } 

    public void notifyNew() { 
     System.out.println("Entering Object::notify: Thread: " + Thread.currentThread() + " at time: " + Instant.now()); 
     obj.notify(); 
     System.out.println("Exiting Object::notify: Thread: " + Thread.currentThread() + " at time: " + Instant.now()); 
    } 

    public void notifyAllNew() { 
     System.out.println("Entering Object::notifyAll: Thread: " + Thread.currentThread() + " at time: " + Instant.now()); 
     obj.notifyAll(); 
     System.out.println("Exiting Object::notifyAll: Thread: " + Thread.currentThread() + " at time: " + Instant.now()); 
    } 
} 

そして最後に、私の質問は、

  1. ある

    New Object wrapper created: Thread: Thread[main,5,main] at time: 2017-03-19T22:48:28.771Z 
    Entering Object::wait: Thread: Thread[Thread One,5,main] at time: 2017-03-19T22:48:28.844Z 
    Entering Object::notifyAll: Thread: Thread[Thread Two,5,main] at time: 2017-03-19T22:48:31.845Z 
    Exiting Object::notifyAll: Thread: Thread[Thread Two,5,main] at time: 2017-03-19T22:48:31.845Z 
    Exiting Object::wait: Thread: Thread[Thread One,5,main] at time: 2017-03-19T22:48:31.845Z 
    

    、コンソールに出力、

    Thread t1 = new Thread(r1); 
        t1.setName("Thread One"); 
        t1.start(); 
    
        Thread t2 = new Thread(r2); 
        t2.setName("Thread Two"); 
        t2.start(); 
    

    を使用してスレッドを開始することはやって、任意の他の良い方法はありますこの?

  2. ObjWrapperを使用しているときに破損するエッジケースはありますか?

編集: 私はオブジェクトをロックするためのより良い方法を探していません。具体的には、wait(),notify()notifyAll()というメソッドの呼び出しをログに記録するだけです。

答えて

0

質問1に関しては、私はむしろ、このアプローチで、あなたはとにかく方法でsynchronizedキーワードを使用する可能性を失うので、信号をオーバーライドし、メソッドを待って、その後、ReentrantLockConditionをサブクラス化します。

質問2については、ここで私が見ることができるメインエッジのケースは、intrinsic lockと本質的な状態のキューに束縛されていることです。 ReentrantLockおよび/またはConditionを使用する場合は、新しいラッパー(簡単なものではないかもしれない)を書く必要があり、複雑さが増してしまう危険性が増し、さらに多くの問題が生じる可能性があります。

おそらくすでにわかっているように、私はむしろ、ラッチ、セマフォ、バリア、ConcurrentCollectionなどのより高いレベルのAPIに固執し、可能な限り低い非常に手間がかかるので、スレッドレベルのスレッド管理が必要です。

+0

お返事ありがとうございます。私の編集を見てください。私は特にObjectクラスの 'wait()'と 'notify()'メソッドに興味があり、呼び出されたときを知りたいと思っています。 – Omer

+0

これらは呼び出したときに呼び出されます。そのため、ラッピング部分についてはわかりません。私はあなたがnotify/notifyAll呼び出しの後にスレッドが実行を開始するときにチェックしようとしていると思います。間違っていると私を修正します。これははるかに広いトピックです – Adonis

+0

あなたは正しいです。状態を待機状態に、またはその逆にすることができる。私が持っているコードへの唯一のフックは、デバッグステートメントです。これらの制約を念頭に置いて、私は 'wait'と' notify'の呼び出しをログに記録します – Omer

関連する問題