@Singleton: Read lock behaves like a write lock and call the same @Stateful. Why?
th.janssen Jun 19, 2014 2:56 PMHi,
I am trying around with ejb @Singleton and the @Lock annotation and I found a strange behavior. The read lock works like a write lock as soon as I access a @Stateful session bean. Both threads call the same @Stateful session bean.
I am using 2 independent client threads in my test. One calling method1() and one calling method2().
Please, can anybody explain to me why this code works like it does?
Thanks!
Thorben
Here is my example (it works as expected if I remove the stateful bean):
@Singleton @Remote(SingletonRemote.class) public class ReadLock implements SingletonRemote { Logger logger = Logger.getLogger(ReadLock.class.getName()); @EJB private MyState myState; @Override @Lock(LockType.READ) public void method1() { this.logger.info("method1 - "+myState.getCounter()); } @Override @Lock(LockType.READ) public void method2() throws Exception { this.logger.info("start method2"); for (int i=0; i < 1000; i++) { myState.incrementCounter(); logger.info("counter: "+myState.getCounter()); } this.logger.info("end method2"); } }
@Test public void test() throws Exception { final CyclicBarrier barrier = new CyclicBarrier(3); final CyclicBarrier startBarrier = new CyclicBarrier(2); Thread t1 = new Thread() { @Override public void run() { try { createInitialContext(); final SingletonRemote readLock1 = TestReadLock.this.getSessionBeanReference("readLock", ReadLock.class.getSimpleName(), SingletonRemote.class, false); startBarrier.await(); for (int i=0; i<100; i++) { readLock1.method1(); } barrier.await(); } catch (Exception e) { Assert.fail(e.getMessage()); } } }; Thread t2 = new Thread() { @Override public void run() { try { createInitialContext(); SingletonRemote readLock2 = TestReadLock.this.getSessionBeanReference("readLock", ReadLock.class.getSimpleName(), SingletonRemote.class, false); readLock2.method2(); barrier.await(); } catch (Exception e) { Assert.fail(e.getMessage()); } } }; t1.start(); startBarrier.await(); t2.start(); barrier.await(); }