Constructor class thread safety in Java reflection

2019-05-29 07:05发布

问题:

Using Java reflection, one can instantiate an object of a class, even via a private constructor, e.g. for

public class MyClass
{
    private MyClass(Object p1, String p2)
    {
        // Constructor with no modifications to static code
    }
}

one can do (in the same or any other class, exception handling omitted for simplification)

public static final Constructor myClass;

static
{
    myClass = MyClass.class.getConstructor(Object.class, String.class);
    myClass.setAccessible(true);
}

and then create new instances of MyClass like

    myClass.newInstance(new Object(), "Test");

Is the above call to newInstance() thread-safe, given that myClass is static?

回答1:

Calling Constructor.newInstance() does not seem to be strictly thread-safe; at least in my openjdk-6 implementation I find a class sun.reflect.NativeConstructorAccessorImpl having a field defined as private int numInvocations; and later on this line of code: if (++numInvocations > ReflectionFactory.inflationThreshold()) { - which may certainly behave otherwise as expected.
Also, in the Constructor class itself, the method acquireConstructorAccessor() is documented with "NOTE that there is no synchronization used here".

But the dodgy behaviour does not seem to result in an overall unexpected behavior, only doing things repeatedly/unnecessarily, thus calling newInstance() in parallel would NOT result in something being screwed up.

Obviously, you can still mess things up with what's done within the instance constructor.



回答2:

Yes, the class instance is static, and the constructor is thread safe, as long as it is not doing anything non-thread safe with the static context of the object.