2015-09-22 12 views
5

私はprocessOutboxというメソッドを持っています。スレッドセーフなものにしたい。私は別のスレッドが1つのスレッドがある間にこのメソッドを呼び出さないようにします。私はそれを次のように実装しました。私はそれを正しくしましたか?実装に抜け穴がありますか?もしあれば、私はそれを解決する方法についてアドバイスをしてください。以下のコンテキストでスレッドの安全性を保証するにはどうすればよいですか?

this.start(); 
    outboxLock.lock(); 
    timer = new Timer(); 
    try{ 
    timer.scheduleAtFixedRate(new TimerTask() { 
      public void run() { 
       processOutbox(); 
      } 
     }, 0, period); 
    } finally{ 
     outboxLock.unlock(); 
    } 
+4

スケジューリングをロックしただけです。実行はまだスレッドセーフではありません。 – Fildor

+0

どのようにすればいいですか?ご意見をお聞かせください。 – mayooran

+0

私はそれをクラスレベルの静的変数に同期させることを提案します。 –

答えて

5

あなたの方法processOutboxにしたい場合は、キーワード​​使用する必要があります:あなたが呼ばれるYOURCLASSのインスタンスを持っているあなたのコード内の場合https://docs.oracle.com/javase/tutorial/essential/concurrency/syncmeth.html

:で

public class YourClass{ 
    public synchronized void processOutbox(){ 
     //do all you want 
    } 
} 

さらに詳しい情報たとえばmyInstanceの場合、processOutbox()へのすべての呼び出しは、インスタンスレベルでロックされるためスレッドセーフになります。例えば

thead2ので ませお待ちしております
YourClass myInstance = new YourClass(); 
YourClass myInstance2= new YourClass(); 
Thread thread1 = new Thread(){ 
    @Override 
    public void run(){ 
     myInstance.processOutbox(); 
    } 
}; 
Thread thread2 = new Thread(){ 
    @Override 
    public void run(){ 
     myInstance2.processOutbox(); 
    } 
} 
thread1.start(); 
thread2.start(); 

:スレッド1が呼び出しに "processOutbox"

しかし、例えばを終了するまで

YourClass myInstance = new YourClass(); 
Thread thread1 = new Thread(){ 
    public void run(){ 
     myInstance.processOutbox(); 
    } 
    } 
Thread thread2 = new Thread(){ 
    public void run(){ 
     myInstance.processOutbox(); 
    } 
    } 
thread1.start(); 
thread2.start(); 

ここthead2をお待ちしております彼らは異なるインスタンス上でメソッドを呼び出しています。

誰かがReentrantLockの使用について具体的に尋ねてきました。だから、私はこの回答が正しいため、この回答を追加しています。

public class YourClass { 
    private Lock outboxLock = new ReentrantLock(); 
    public void processOutbox() { 
     outboxLock.lock() 
     try { 
      // do stuff 
     } finally { 
      outboxLock.unlock() 
     } 
    } 
} 

あなたも、あなたは彼らが代わりのtryLockを使用することによってブロックさせることなく、ロックの外に他のスレッドを維持する事を、行うことができますので、私はこれを具体的に言及します。

public class YourClass { 
    private Lock outboxLock = new ReentrantLock(); 
    public void processOutbox() { 
     if(outboxLock.tryLock()) { 
      try { 
       // do stuff 
      } finally { 
       outboxLock.unlock() 
      } 
     } 
    } 
} 
+0

** 1つのスレッドがある間に別のスレッドがこのメソッドを呼び出さないようにする** –

+0

Java API:「あるスレッドがオブジェクトに対して同期メソッドを実行しているときに、最初のスレッドがオブジェクトで完了するまで、オブジェクトブロック(実行を中断する)。 –

+0

リエントラントロックを使用して同じことを達成するにはどうすればよいですか?助言をお願いします:) – mayooran

関連する問題