Reputation: 5689
I have a synchronized method that appears to be 'using' the synchronization for significantly longer than it should. It looks something like;
public static synchronized void myMethod(MyParameter p) {
//body (not expensive)
}
The call looks like;
myMethod(generateParameter());
Where generateParameter()
is known to be a very expensive (takes a long time) call. My thinking is that the mutex on the myMethod
class is blocked during the execution of generateParameter()
is this what happens? I'm finding it a different problem to debug but this is what appears to be going on.
Upvotes: 6
Views: 353
Reputation: 49231
No it is not what happens.
Method generateParameter
is executed before call to myMethod
.
In Java, all method arguments are always evaluated before method call.
The specification of method call explains it in detail (thanks to Victor Sorokin).
At run time, method invocation requires five steps. First, a target reference may be computed. Second, the argument expressions are evaluated. Third, the accessibility of the method to be invoked is checked. Fourth, the actual code for the method to be executed is located. Fifth, a new activation frame is created, synchronization is performed if necessary, and control is transferred to the method code.
Your code is the same as the one below, except of new variable:
MyParameter p = generateParameter();
myMethod(p);
Upvotes: 5
Reputation: 21616
Instead of static synchronized void myMethod(p)
its better to use ReadWriteLock
for your resources:
MyParameter p = generateParameter();
myMethod(p){
ReadWriteLock readWriteLock = new ReentrantReadWriteLock();
readWriteLock.readLock().lock();
// multiple readers can enter this section
// if not locked for writing, and not writers waiting
// to lock for writing.
readWriteLock.readLock().unlock();
readWriteLock.writeLock().lock();
// only one writer can enter this section,
// and only if no threads are currently reading.
readWriteLock.writeLock().unlock();
}
Upvotes: 1
Reputation: 31
"the mutex on the myMethod class is blocked during the execution of generateParameter()"
As far as I know the lock is not acquired until the execution of the generateParameter
function ends.
Upvotes: 0
Reputation: 77226
The thread executing myMethod
enters the object's monitor at the beginning of the method and holds it until it exits. Any operations done inside the method are synchronized
, but all call parameters are evaluated before the call is made, so generateParameter
is not executing inside myMethod
's lock window.
If generateParameter
has any synchronization on it, though, it could be contending for the same lock, since without an explicit synchronization object the JVM synchronizes on the object whose method is being called.
I strongly suggest profiling the code to determine where it's really getting stuck.
Upvotes: 2
Reputation: 15675
That can't be it; the generateParameter()
call is executed first, and its results are then given as an argument to the myMethod
call, which then grabs the mutex.
Is it taking long, or is it indefinitely blocked? (a deadlock)
Upvotes: 5