If you want to make your method processOutbox, you should use the keyword synchronized
:
public class YourClass{
public synchronized void processOutbox(){
//do all you want
}
}
More info at:https://docs.oracle.com/javase/tutorial/essential/concurrency/syncmeth.html
If in your code you have an instance of YourClass called for example myInstance
, all calls to processOutbox()
will be thread safe because they will be locked at instance level.
For example:
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();
Here thead2 will be waiting until thread1 finishes the call to "processOutbox"
But for example:
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 will NOT wait because they are calling the method on different instances.
Someone specifically asked about using ReentrantLock -- So I'm adding that response on to this one, because this one is correct.
public class YourClass {
private Lock outboxLock = new ReentrantLock();
public void processOutbox() {
outboxLock.lock()
try {
// do stuff
} finally {
outboxLock.unlock()
}
}
}
I mention this specifically because you can also do things, where you keep other threads out of the lock without causing them to block by using tryLock instead.
public class YourClass {
private Lock outboxLock = new ReentrantLock();
public void processOutbox() {
if( outboxLock.tryLock() ) {
try {
// do stuff
} finally {
outboxLock.unlock()
}
}
}
}