EJB3.0多线程访问的同步问题

一般EJB持久化实体的流程如下:

1.初始化上下文Context ctx

2.调用ctx的lookup方法获取具体的dao

3.调用dao的具体方法

由于多用户同时操作同一个对象,导致数据不同步的问题。这就是所谓多线程引发的问题。

简单地举例说明上面那个问题:

(银行帐号存取款问题)某一个银行帐号里边现有存款1万,假设两个人A,B同时操作这个帐号,A作存款100操作,B作取款200操作

在A存款的某一时刻,银行系统先读取存款1万后+100,还没来得及将总合1万1百块钱存入数据库,B就作取款操作,此时系统读取1万块,再作-200操作,B处理完成后,帐号总额应该是9800块钱。但在B处理完后,A继续执行存款操作(将1万1百块存入数据库,此时,数据库值从9800一下子变成了10100块)

我们知道JAVA用synchronized关键字作为同步排斥的,但前提是,同一个对象的所有锁,必须是指定同一个对象,否则加锁等于没锁。

经测试EJB每一次获取dao对象时,每一个对象都是不同的对象,所以不能简单地用调用对象所指向的锁(this或在方法前加synchronized),

public synchronized void fuck(){...}   public void fuck2(){  synchronized(this){...}  }  

而应该使用静态锁。

JAVA当中,每一类对象在会有一份字节码保存于内存之中,有且只有一份。所以ejb当中,应当使用静态同步锁来排斥其他线程对同一个方法的访问,伪码如下:

class Fuck{

public void fuck3(){  synchronized(Fuck.class){...}  } 

}

我使用JUnit写了测试,用两个线程同时跑,两个线程跑时,都模拟了EJB创建DAO过程,并调用同一个DAO内同一个方法。

 @Test
    public void fuck() throws NamingException{
 

     new Thread(new Runnable(){
      @Override
      public void run() {
       try {
           
           while(true){
               fuckDao2 = (FuckDao)ctx.lookup("Fuck/remote");
               fuckDao2.done("00000"); 
           }
           
    } catch (NamingException e) {
     // TODO Auto-generated catch block
     e.printStackTrace();
    }
      }
     }).start();
     
           while(true){
               fuckDao = (FuckDao)ctx.lookup("FuckImpl/remote");
               fuckDao.done("22222"); 
           }
   
    }

####dao下同步方法的代码

    public void done(String name) {
     synchronized(FuckImpl.class){
      int l = name.length();
      for(int i=0;i<l;i++){
       System.out.println(name.charAt(i));
      }
     }
  
 }

经测试,以上方法能够解决EJB当中同一类DAO的不同实例同时调用DAO里同一个方法的排斥同步问题。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值