In the Proxy object (the object implementing java.lang.reflect.InvocationHandler), I am trying to set an instance variable in the proxied object.
Like the following:
public class ServiceProxy implements InvocationHandler {
private final Object proxiedObject;
private ServiceProxy(final Object object) {
this.proxiedObject = object;
}
public static Object newInstance(final Object object) {
return Proxy.newProxyInstance(object.getClass().getClassLoader(), object.getClass().getInterfaces(), new ServiceProxy(object));
}
public Object invoke(final Object proxy, final Method method, final Object[] args) throws Throwable {
Object result = null;
MyObject mo = new MyObject();
// Is the following safe when the proxiedObject is being acceessed by multiple threads?
final Field sessionField = this.proxiedObject.getClass().getSuperclass().getDeclaredField("mo");
sessionField.setAccessible(true);
sessionField.set(this.object, mo);
result = method.invoke(this.proxiedObject, args);
return result;
}
}
Is this safe?
EDIT:
Actual code:
Object result = null;
Session session = HibernateUtil.getSessionFactory().getCurrentSession()
// Is the following save when the proxiedObject is being acceessed by multiple threads?
final Field sessionField = this.proxiedObject.getClass().getSuperclass().getDeclaredField("session");
sessionField.setAccessible(true);
sessionField.set(this.object, session);
result = method.invoke(this.proxiedObject, args);
return result;
Edit2: The proxied object is being called from GWT client that calls multiple methods of the same proxied object at the same time. When this happens, I got the session instance field (of proxied class) to be closed and opened in unexpected manner.
No, unless
moisvolatile. If themofield isvolatilethen this will properly cross a memory barrier and the updates to themofield will be seen by all threads.It is important to realize that if the
MyObjectis not immutable, additional concurrency issues will result even ifmoisvolatile.Edit:
Thanks to @jtahlborn comments on this. I've been doing some reading and I'm now pretty sure that the
volatilewill also protect theMyObjectfrom being partially initialized.Due to constructor instruction reordering possibilities, there is no guarantee that the
MyObjecthas been fulling constructed when its referenced is shared between threads. Onlyfinalfields in a constructor are guaranteed to be properly initialized when a constructor finishes. Any other fields may or may not have been initialized and so you will need to synchronize on the object before the multiple threads can start accessing it.However, if the
mofield is volatile, then the "happens before" guarantee also ensures that theMyObjecthas been fully initialized. The compiler is not allowed to reorder those instructions past the publishing of avolatilevariable. See: