This multi-threaded application access a set of web services that update parts of a database. The problem is messages arriving in the rabbit mq bus are asynchronous and are not really aware of each other. So there might be a time that 2 different requests that access the same part of a database at the same time.
Working with this I've remembered 2 different solutions plus I've learned another one:
1.) Using synchronized keyword in a method. This is what I've used, because fortunately all my web service calls are in a single class. Basically it locks the method and only 1 thread can access the method at a time.
public synchronized ClientResponse syncWebServiceCall(
WebResource webResource) {
// code here
}
2.) The next is a statement block, similar to no 1 except that you used a mutex object to lock. The mutex object can be the object where the method is defined or another object. In this way we don't necessarily lock the whole method.
public ClientResponse syncWebServiceCall(
WebResource webResource) {
synchronized(this) {
// code
}
}
3.) The last one. Which I've just learned. Using ReentrantLock: http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/locks/ReentrantLock.html Modifying the example:
class X {
private final ReentrantLock lock = new ReentrantLock();
public ClientResponse syncWebServiceCall() {
lock.lock(); // block until condition holds
try {
// ... method body
} finally {
lock.unlock()
}
}
}
0 nhận xét:
Đăng nhận xét