Re: Docs: EJB 3.1 Singleton documentation

2008-08-27 Thread Martin Vysny
On Tue, 2008-08-26 at 11:12 -0700, David Blevins wrote:
 On Aug 26, 2008, at 5:23 AM, Martin Vysny wrote:
 
  Many thanks for clarifying on how the locks works! One more question,
  just to be 100% sure :) . Recently I studied the java memory model a  
  bit
  (there is beautiful FAQ located at [1]) and I'd like to ask:
 
  Let's assume that the execution exited some method m1 protected by
  Lock.READ (or Lock.WRITE) and is about to enter some method m2 (in the
  same Singleton bean) protected by Lock.WRITE. Is any operation invoked
  in method m1 guaranteed to happen-before any operation invoked in
  method m2?
 
 Those details are better described on this page:
 
   http://cwiki.apache.org/OPENEJBx30/singleton-beans.html
 
 I've slightly tweaked it to make the connection with ReadWriteLock  
 stronger and to explicitly mention we use a ReentrantReadWriteLock.   
 Hopefully people will follow those links.
 
 Here are a couple quotes from those docs that answer your questions a  
 little more specifically:
 
All ReadWriteLock implementations must guarantee that the
memory synchronization effects of writeLock operations (as
specified in the Lock interface) also hold with respect to the
associated readLock. That is, a thread successfully acquiring
the read lock will see all updates made upon previous release
of the write lock.
 
  -- 
 http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/locks/ReadWriteLock.html
 
Reentrancy also allows downgrading from the write lock to a
read lock, by acquiring the write lock, then the read lock and
then releasing the write lock. However, upgrading from a read
lock to the write lock is not possible.
 
  -- 
 http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/locks/ReentrantReadWriteLock.html
 
 
 We could probably quote some of those two javadocs if there were one  
 or two really critical things we think people should know above all  
 else.  If you have any thoughts on that regard that'd be great.
 
 -David
 

Thanks David, the documentation now answers my question very clearly. I
think you could explicitly quote this sentence: That is, a thread
successfully acquiring the read lock will see all updates made upon
previous release of the write lock. - it sums an answer to the question
very nicely and simply. However, I have no other questions, the
documentation is perfect, thanks :)
Sincerely
Martin


signature.asc
Description: This is a digitally signed message part


Re: Docs: EJB 3.1 Singleton documentation

2008-08-26 Thread Martin Vysny
On Mon, 2008-08-25 at 20:23 -0700, David Blevins wrote:
 Hi Martin,
 
 On Aug 25, 2008, at 4:33 AM, Martin Vysny wrote:
 
  Hi David,
   impressive work indeed, thank you very much! I am especially grateful
  for the Singleton and Startup functionality which I missed.
 
 Thanks!  It's definitely great to have a standard way to do this in  
 the EJB world.
 
  I have one
  question: in your example (the ComponentRegistryBean example) a simple
  HashMap is used which is thread unsafe. Does that mean that only a
  single thread (the one which created the bean) will access the bean?
  Nope, that's not it - multiple threads can access methods with
  Lock.READ. What does the specification say about the thread
  safety/multithreading issues? Must the bean be thread-safe or  
  container
  will mark all methods as synchronized? Can the user code rely on some
  locking mechanisms (or invariants) performed by the container (for
  example, will Lock.WRITE always perform lock on the bean class?)
  Sorry if it is a dumb question and I'm missing something obvious :)
 
 Good feedback.  Thank you for sending it!
 
 Clearly my explanation is not doing what it should :)   I do see a bug  
 too now that I look closer, too.  The getComponents() method should  
 return a copy of components.values() or someone could get a  
 ConcurrentModificationException.
 
 I've changed/expanded on the text in the example.  Pasted it here  
 below as well.  Let me know if it's any better.  We'll keep trying  
 till we get something that's easy to understand and doesn't leave the  
 reader with a bunch of questions.
 
 
Unless specified explicitly on the bean class or a method, the
default @Lock value is @Lock(WRITE). The code above uses the
@Lock(READ) annotation on bean class to change the default so
that multi-threaded access is granted by default. We then only
need to apply the @Lock(WRITE) annotation to the methods that
modify the state of the bean.
 
Essentially @Lock(READ) allows multithreaded access to the
Singleton bean instance unless someone is invoking an
@Lock(WRITE) method. With @Lock(WRITE), the thread invoking the
bean will be guaranteed to have exclusive access to the Singleton
bean instance for the duration of its invocation. This
combination allows the bean instance to use data types that are
not normally thread safe. Great care must still be used, though.
 
In the example we see ComponentRegistryBean using a
java.util.HashMap which is not synchronized. To make this ok we
do three things:
 
 1. Encapsulation. We don't expose the HashMap instance directly;
including its iterators, key set, value set or entry set.
 
 2. We use @Lock(WRITE) on the methods that mutate the map such
as the put() and remove() methods.
 
 3. We use @Lock(READ) on the get() and values() methods as they
do not change the map state and are guaranteed not to be
called at the same as any of the @Lock(WRITE) methods, so we
know the state of the HashMap is no being mutated and
therefore safe for reading.
 
The end result is that the threading model for this bean will
switch from multi-threaded access to single-threaded access
dynamically as needed depending on the which methods are being
invoked. This gives Singletons a bit of an advantage over
Servlets for processing multi-threaded requests.
 
 http://cwiki.apache.org/OPENEJBx30/singleton-example.html
 
 Feel free to kick it back with changes/tweaks or other questions.   
 Sometimes a word added here or there can make things more clear.   
 These docs are likely going to be a primary source of singleton  
 information for a while so we definitely want them to be as  
 informative as possible.
 
 -David
 
 

Many thanks for clarifying on how the locks works! One more question,
just to be 100% sure :) . Recently I studied the java memory model a bit
(there is beautiful FAQ located at [1]) and I'd like to ask:

Let's assume that the execution exited some method m1 protected by
Lock.READ (or Lock.WRITE) and is about to enter some method m2 (in the
same Singleton bean) protected by Lock.WRITE. Is any operation invoked
in method m1 guaranteed to happen-before any operation invoked in
method m2?

If not, then the example is still not thread-safe :) The happen-before
is discussed in the What does synchronization do? section of the FAQ.
Of course, if the EJB container simply uses correct synchronization then
the answer is yes. However there may be other ways to synchronize (using
DB locks or the like) which could not be as safe (in Java memory model).
Please feel free to contact me if I wasn't clear enough.
Martin

[1]: http://www.cs.umd.edu/~pugh/java/memoryModel/jsr-133-faq.html


signature.asc
Description: This is a digitally signed message part


Re: Docs: EJB 3.1 Singleton documentation

2008-08-26 Thread David Blevins


On Aug 26, 2008, at 5:23 AM, Martin Vysny wrote:


Many thanks for clarifying on how the locks works! One more question,
just to be 100% sure :) . Recently I studied the java memory model a  
bit

(there is beautiful FAQ located at [1]) and I'd like to ask:

Let's assume that the execution exited some method m1 protected by
Lock.READ (or Lock.WRITE) and is about to enter some method m2 (in the
same Singleton bean) protected by Lock.WRITE. Is any operation invoked
in method m1 guaranteed to happen-before any operation invoked in
method m2?


Those details are better described on this page:

 http://cwiki.apache.org/OPENEJBx30/singleton-beans.html

I've slightly tweaked it to make the connection with ReadWriteLock  
stronger and to explicitly mention we use a ReentrantReadWriteLock.   
Hopefully people will follow those links.


Here are a couple quotes from those docs that answer your questions a  
little more specifically:


  All ReadWriteLock implementations must guarantee that the
  memory synchronization effects of writeLock operations (as
  specified in the Lock interface) also hold with respect to the
  associated readLock. That is, a thread successfully acquiring
  the read lock will see all updates made upon previous release
  of the write lock.

-- 
http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/locks/ReadWriteLock.html

  Reentrancy also allows downgrading from the write lock to a
  read lock, by acquiring the write lock, then the read lock and
  then releasing the write lock. However, upgrading from a read
  lock to the write lock is not possible.

-- 
http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/locks/ReentrantReadWriteLock.html


We could probably quote some of those two javadocs if there were one  
or two really critical things we think people should know above all  
else.  If you have any thoughts on that regard that'd be great.


-David



Re: Docs: EJB 3.1 Singleton documentation

2008-08-25 Thread Martin Vysny
On Sat, 2008-08-23 at 02:04 -0700, David Blevins wrote:
 All,
 
 We've implemented the new EJB 3.1 javax.ejb.Singleton bean type.   
 Singletons are a new type of Session bean being added to the EJB 3.1  
 specification.  They provide some much needed functionality to the  
 world of EJB and will be part of the coming OpenEJB 3.1 release.
 
 http://openejb.apache.org/singleton-beans.html
 
 http://openejb.apache.org/singleton-example.html
 
 Enjoy the first ever @Singleton bean implementation!
 
 A large part of our motivation for implementing this early is to  
 gather feedback for the specification itself.  This is one of those  
 rare times where you can not only give feedback about our  
 implementation but about the actual API as well!
 
 Give it a try and let us know what you think!
 
 -David
 
 Example source code: svn co 
 http://svn.apache.org/repos/asf/openejb/trunk/openejb3/examples/simple-singleton/
 

Hi David,
  impressive work indeed, thank you very much! I am especially grateful
for the Singleton and Startup functionality which I missed. I have one
question: in your example (the ComponentRegistryBean example) a simple
HashMap is used which is thread unsafe. Does that mean that only a
single thread (the one which created the bean) will access the bean?
Nope, that's not it - multiple threads can access methods with
Lock.READ. What does the specification say about the thread
safety/multithreading issues? Must the bean be thread-safe or container
will mark all methods as synchronized? Can the user code rely on some
locking mechanisms (or invariants) performed by the container (for
example, will Lock.WRITE always perform lock on the bean class?)
Sorry if it is a dumb question and I'm missing something obvious :)
Sincerely,
Martin



signature.asc
Description: This is a digitally signed message part


Re: Docs: EJB 3.1 Singleton documentation

2008-08-25 Thread David Blevins

Hi Martin,

On Aug 25, 2008, at 4:33 AM, Martin Vysny wrote:


Hi David,
 impressive work indeed, thank you very much! I am especially grateful
for the Singleton and Startup functionality which I missed.


Thanks!  It's definitely great to have a standard way to do this in  
the EJB world.



I have one
question: in your example (the ComponentRegistryBean example) a simple
HashMap is used which is thread unsafe. Does that mean that only a
single thread (the one which created the bean) will access the bean?
Nope, that's not it - multiple threads can access methods with
Lock.READ. What does the specification say about the thread
safety/multithreading issues? Must the bean be thread-safe or  
container

will mark all methods as synchronized? Can the user code rely on some
locking mechanisms (or invariants) performed by the container (for
example, will Lock.WRITE always perform lock on the bean class?)
Sorry if it is a dumb question and I'm missing something obvious :)


Good feedback.  Thank you for sending it!

Clearly my explanation is not doing what it should :)   I do see a bug  
too now that I look closer, too.  The getComponents() method should  
return a copy of components.values() or someone could get a  
ConcurrentModificationException.


I've changed/expanded on the text in the example.  Pasted it here  
below as well.  Let me know if it's any better.  We'll keep trying  
till we get something that's easy to understand and doesn't leave the  
reader with a bunch of questions.



  Unless specified explicitly on the bean class or a method, the
  default @Lock value is @Lock(WRITE). The code above uses the
  @Lock(READ) annotation on bean class to change the default so
  that multi-threaded access is granted by default. We then only
  need to apply the @Lock(WRITE) annotation to the methods that
  modify the state of the bean.

  Essentially @Lock(READ) allows multithreaded access to the
  Singleton bean instance unless someone is invoking an
  @Lock(WRITE) method. With @Lock(WRITE), the thread invoking the
  bean will be guaranteed to have exclusive access to the Singleton
  bean instance for the duration of its invocation. This
  combination allows the bean instance to use data types that are
  not normally thread safe. Great care must still be used, though.

  In the example we see ComponentRegistryBean using a
  java.util.HashMap which is not synchronized. To make this ok we
  do three things:

   1. Encapsulation. We don't expose the HashMap instance directly;
  including its iterators, key set, value set or entry set.

   2. We use @Lock(WRITE) on the methods that mutate the map such
  as the put() and remove() methods.

   3. We use @Lock(READ) on the get() and values() methods as they
  do not change the map state and are guaranteed not to be
  called at the same as any of the @Lock(WRITE) methods, so we
  know the state of the HashMap is no being mutated and
  therefore safe for reading.

  The end result is that the threading model for this bean will
  switch from multi-threaded access to single-threaded access
  dynamically as needed depending on the which methods are being
  invoked. This gives Singletons a bit of an advantage over
  Servlets for processing multi-threaded requests.

http://cwiki.apache.org/OPENEJBx30/singleton-example.html

Feel free to kick it back with changes/tweaks or other questions.   
Sometimes a word added here or there can make things more clear.   
These docs are likely going to be a primary source of singleton  
information for a while so we definitely want them to be as  
informative as possible.


-David