Question

I need to call some synchronized methods via Java's Reflection API. Let's say that I have:

public final synchronized void doSomething() {
    Thread.sleep(1000);
}

If I called this method directly from two threads one thread would enter the method and the other thread would have to wait until the first thread has left the method block (after one second). Then the other thread could enter the method and any other threads would need to wait.

Is there any difference if I don't call the method directly but call it through reflection? Would the "blocking"-behaviour be the same?

Était-ce utile?

La solution

The blocking behavior will be exactly the same as if you call that method without reflection. Basically JVM below will execute same logic. You can try it yourself with below code snippet:

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class SynchronizedReflectionTest {

public static void main(String[] args) {
    SynchronizedReflectionTest test = new SynchronizedReflectionTest();

    for(int i=0; i<5; i++) {
        final int finalI = i;
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    Method someThing = SynchronizedReflectionTest.class.getDeclaredMethod("someThing", new Class[]{int.class});
                    someThing.invoke(test, finalI);
                } catch (NoSuchMethodException e) {
                    e.printStackTrace();
                } catch (InvocationTargetException e) {
                    e.printStackTrace();
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }
}

public synchronized void someThing(int nr)
{
    System.out.println("Executing someThing from "+nr);
    try {
        Thread.sleep(1000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    System.out.println("Finished executing from nr "+nr);
}

}

From the print results you can see that method calls are synchronized. Print results:

Executing someThing from 0
Finished executing from nr 0
Executing someThing from 4
Finished executing from nr 4
Executing someThing from 3
Finished executing from nr 3
Executing someThing from 2
Finished executing from nr 2
Executing someThing from 1
Finished executing from nr 1

JVM guarantee that code guarded by lock will execute in synchronized blocks and if it will depend from type of method invocation reflection mechanism will be completely not safe and useless.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top