lynks
lynks

Reputation: 5689

Java synchronized method with expensive parameters

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

Answers (5)

Grzegorz Żur
Grzegorz Żur

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

tokhi
tokhi

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

SoulSeek
SoulSeek

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

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

Miquel
Miquel

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

Related Questions