0

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.

6
  • what is the actual problem you are having. you hinted at a "threading issue" below, what is it? Commented Jul 19, 2012 at 16:44
  • i don't understand what you mean about "closed and opened in unexpected manner". secondly, if you are implying that you are using the hibernate Session from multiple threads, you should know that Hibernate Sessions are not thread-safe. Commented Jul 19, 2012 at 16:52
  • Thread 1 open session, thread 1 use open session .. Then thread 2 request to open the session if not already opened.. Then thread 1 close the session .. Then thread 2 try to use the session (that was closed) and hence an exception arise here.... Commented Jul 19, 2012 at 16:58
  • I think using SessionFactory will solve the problem.. correct? Commented Jul 19, 2012 at 16:59
  • yes, each thread should be using its own instance of Session (using the SessionFactory to acquire a Session instance as needed). Commented Jul 19, 2012 at 17:06

1 Answer 1

2

Is the following safe when the proxiedObject is being acceessed by multiple threads?

No, unless mo is volatile. If the mo field is volatile then this will properly cross a memory barrier and the updates to the mo field will be seen by all threads.

It is important to realize that if the MyObject is not immutable, additional concurrency issues will result even if mo is volatile.


Edit:

Thanks to @jtahlborn comments on this. I've been doing some reading and I'm now pretty sure that the volatile will also protect the MyObject from being partially initialized.

Due to constructor instruction reordering possibilities, there is no guarantee that the MyObject has been fulling constructed when its referenced is shared between threads. Only final fields 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 themo field is volatile, then the "happens before" guarantee also ensures that the MyObject has been fully initialized. The compiler is not allowed to reorder those instructions past the publishing of a volatile variable. See:

Sign up to request clarification or add additional context in comments.

17 Comments

if the mo field is volatile, then the MyObject will be correctly published due to volatile semantics. MyObject does not need to be immutable or have all final fields or any other crazy requirements. (obviously if mo is not volatile then all bets are off).
the jdk 5 memory model strengthened volatile so that nothing can be re-ordered across it. if this were not the case, ReentrantLock, ConcurrentHashMap and most of the rest of the new concurrent utils would be useless. volatile now has the same strength synchronized in terms of memory visibility.
Synchronization Order, bullet point 2. there's nothing specific to constructors there because nothing specific is needed. everything that happens before the volatile write (object construction) is visible after the volatile read. just like assignment in a synchronized block.
@assylias - you can't read the object fields in another thread without first reading the volatile reference (obviously i'm assuming that the volatile reference is the means of publishing the object). so it would be "construction of object(t1) -> w(t1) -> r(t2) -> read object fields(t2)" (using t1 and t2 to represent two separate threads).
Yeah @assylias. I see no way for the order of execution to be: object construction -> w -> read object fields -> r. The only thread that would be able to read the object fields before reading the volatile variable would be the first thread which wouldn't have an issue.
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.