3

I want an object that can be created by any thread, but the moment a thread calls myObject.use() it can only be used by that thread until myObject.release() is called.

I don't want to force the developers to have to wrap all method calls for this object/class in synchronized blocks (which I know could be used to approximate this functionality) as that's likely to lead to misuse of the object if they forget to wrap all calls from myObject.use() to myObject.release() in the same synchronized block.

Is this possible?

Could it be done with a ReentrantLock?

Warren Dew
  • 8,790
  • 3
  • 30
  • 44
Don Rhummy
  • 24,730
  • 42
  • 175
  • 330
  • Define _used by that thread_. – Sotirios Delimanolis May 05 '16 at 00:33
  • 2
    Sounds like an *object pool* to me. – Elliott Frisch May 05 '16 at 00:34
  • @SotiriosDelimanolis Some instance in a thread calls the myObject instance's methods – Don Rhummy May 05 '16 at 00:36
  • @ElliottFrisch That is probably a good idea. Can you say a bit more about why that's better than implementing this functionality in the class definiteion itself? – Don Rhummy May 05 '16 at 00:36
  • And what would you want to happen if another thread did? I think @ElliottFrisch is correct here. – Sotirios Delimanolis May 05 '16 at 00:37
  • @SotiriosDelimanolis Ideally it would get an exception instead of blocking – Don Rhummy May 05 '16 at 00:37
  • There are a number of ways to do this. The pool is probably the best. You won't even be able to release an object unless it's available. Makes for cleaner code (handle exception at acquisition, not at use). Another option is to wrap your object in a proxy (think JDK proxies) and place the logic for atomically acquiring the instance before delegating to the real instance, then release the object. Then there's the full AOP solution which would be similar to the proxy. – Sotirios Delimanolis May 05 '16 at 00:42
  • Can I assume that "specific method" is a create method and the object itself stored in a ThreadLocal? – Jaumzera May 05 '16 at 00:57

1 Answers1

1

Sure it can be done. The use() method should be synchronized, so it can be called by only one thread at a time, and store the calling thread as the locking thread in a private volatile variable. All calls - including use() - should first check if there is a stored locking thread and immediately return - or throw an exception if you prefer - if there is such a thread and it doesn't match the calling thread. release() should also be synchronized and can remove the stored locking thread, allowing the next call to use() to store a new locking thread.

Warren Dew
  • 8,790
  • 3
  • 30
  • 44