【问题标题】:Call synchronized method from reflection从反射调用同步方法
【发布时间】:2014-04-05 22:02:27
【问题描述】:

我需要通过 Java 的反射 API 调用一些同步方法。 假设我有:

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

如果我直接从两个线程调用此方法,一个线程将进入该方法,而另一个线程必须等到第一个线程离开方法块(一秒钟后)。然后其他线程可以进入该方法,任何其他线程都需要等待。

如果我不直接调用该方法而是通过反射调用它,有什么区别吗? “阻塞”行为是否相同?

【问题讨论】:

  • 如果您使用反射,您的反射代码也将存在于线程中...

标签: java reflection synchronization block synchronized


【解决方案1】:

阻塞行为将与您在没有反射的情况下调用该方法完全相同。基本上下面的 JVM 将执行相同的逻辑。您可以使用以下代码 sn-p 自己尝试:

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保证被锁保护的代码将在同步块中执行,如果它依赖于方法调用的类型,反射机制将完全不安全和无用。

【讨论】:

    猜你喜欢
    • 2017-09-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多