我需要通过Java的Reflection API调用一些同步方法。 让我们说我有:
public final synchronized void doSomething() {
Thread.sleep(1000);
}
如果我直接从两个线程调用此方法,则一个线程将进入该方法,另一个线程必须等到第一个线程离开方法块(一秒钟之后)。然后另一个线程可以进入该方法,任何其他线程都需要等待。
如果我不直接调用该方法但通过反射调用它,有什么区别吗? "阻止" -behaviour会不一样?
答案 0 :(得分:2)
阻止行为与您在没有反射的情况下调用该方法完全相同。基本上下面的JVM将执行相同的逻辑。您可以使用以下代码段自行尝试:
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);
}
}
从打印结果中,您可以看到方法调用已同步。 打印结果:
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保证锁定的代码将在同步块中执行,如果它依赖于方法类型的调用,反射机制将完全不安全无用。