1 Reply Latest reply on Jun 20, 2014 3:14 AM by th.janssen

    @Singleton: Read lock behaves like a write lock and call the same @Stateful. Why?

    th.janssen

      Hi,

       

      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();
      }