4

processOutbox というメソッドがあります。スレッドセーフにしたい。あるスレッドがこのメソッドを使用しているときに、別のスレッドがこのメソッドを呼び出すことは望ましくありません。以下の方法で実装しました。私はそれを正しくしましたか?実装に抜け穴はありますか? ある場合は、どのように解決すればよいかアドバイスをお願いします。

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

2 に答える 2

5

メソッドを processOutbox にしたい場合は、次のキーワードを使用する必要がありますsynchronized

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

詳細: https://docs.oracle.com/javase/tutorial/essential/concurrency/syncmeth.html

コード内に example と呼ばれる YourClass のインスタンスがある場合myInstance、すべての呼び出し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 は、thread1 が「processOutbox」への呼び出しを終了するまで待機します。

しかし、例えば:

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();

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()
            }
        }
    }
}
于 2015-09-22T07:04:42.680 に答える
1

CountDownLatch同期には a を使用します。

于 2015-09-22T08:08:32.700 に答える