Synchronized Java Method with Costly Parameters

I have a synchronized method that seems to β€œuse” synchronization much longer than necessary. It looks something like this:

public static synchronized void myMethod(MyParameter p) { //body (not expensive) } 

The call is as follows:

 myMethod(generateParameter()); 

Where generateParameter() is known to be very expensive (time consuming). My thinking is that the mutex in the myMethod class myMethod locked at run time generateParameter() - is that what happens? I find this to be another problem for debugging, but this is what seems to be happening.

+6
source share
5 answers

It cannot be; the generateParameter() call is made first, and its results are then specified as an argument to the myMethod call, which then captures the mutex.

Does it take a lot of time, or is it infinitely blocked? (dead end)

+5
source

No, it is not.

The generateParameter method is executed before calling myMethod .

In Java, all method arguments are always evaluated before the method is called.

the method call specification explains this in detail (thanks to Victor Sorokin).

When you start a method call, five steps are required. First, the target link can be computed. Secondly, argument expressions are computed. Thirdly, the availability of the method for calling is checked. Fourth, the actual code for the method to be executed is found. Fifth, a new activation frame is created, if necessary, synchronization is performed, and control is transferred to the method code.

Your code is the same as below, except for the new variable:

 MyParameter p = generateParameter(); myMethod(p); 
+5
source

The execution of the myMethod enters the object monitor at the beginning of the method and holds it until it ends. Any operations performed inside the method are synchronized , but all parameters of the call are evaluated before the call is made, therefore generateParameter not executed inside the lock window myMethod .

If generateParameter has any kind of synchronization, it can compete for the same lock, because without an explicit synchronization object, the JVM synchronizes with the object whose method is called.

I highly recommend profiling the code to determine where it really gets stuck.

+2
source

Instead of static synchronized void myMethod(p) it is 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(); } 
+1
source

"the mutex in the myMethod class is blocked at run time generateParameter ()"

As far as I know, a lock will not be obtained until the generateParameter function is complete.

0
source

Source: https://habr.com/ru/post/959047/


All Articles