lcx_1989210 2016-07-14 06:34 采纳率: 33.3%
浏览 789

关于多线程下Synchronized锁和ReentrantLock的问题

  1. 现在有如下的业务场景:
    数据库里边只有id,time2个字段,数据库里边id是自增的。现在需要对id进行一次更新之后,再去进行查询,
    以期获得最新的id,并返回给业务方。
    public IDGenerateEntityDb execSql(final String time) throws Exception {
    DaoWrapper wrapper = BaseDaoWrapperFactory.getDaoWrapper();
    final String sql = "replace into tbl (time) values(" + time + ")";
    IDGenerateEntityDb db = new IDGenerateEntityDb();
    final Lock lock = new ReentrantLock();
    lock.lock();
    Long id = (Long) wrapper.execInsert(sql, new IPreparedStatementHandler() {
    public Object exec(PreparedStatement paramPreparedStatement) throws SQLException {
    int s = paramPreparedStatement.executeUpdate(sql);// 返回的是执行的条数
    Long idLong = null;
    try {
    if (s == 1 || s == 2) { // 表明执行成功
    ResultSet set = paramPreparedStatement.executeQuery(" SELECT * from tbl where time= " + time);
    while (set.next()) {
    idLong = set.getLong("id");
    System.out.println(idLong);
    }
    }
    } catch (Exception e) {
    e.printStackTrace();
    } finally {
    lock.unlock();
    }
    return idLong;
    }
    });
    db.setId(id);
    return db;
    }

    用这种方式的时候,拿到的结果就会有重复数据,但是将ReentrantLock改为Synchronized后拿到的结果就正常了,这是什么原因呢。是不是加锁的额方式不对呢?
    
  • 写回答

2条回答 默认 最新

  • july_apple 2016-07-16 06:18
    关注

    finally代码块中执行lock.unlock(),此时释放了锁,但在释放锁之前,已经有返回值了。你将return idLong;放到lock.unlock();之后就可以了。

    评论

报告相同问题?

悬赏问题

  • ¥20 有关区间dp的问题求解
  • ¥15 多电路系统共用电源的串扰问题
  • ¥15 slam rangenet++配置
  • ¥15 有没有研究水声通信方面的帮我改俩matlab代码
  • ¥15 对于相关问题的求解与代码
  • ¥15 ubuntu子系统密码忘记
  • ¥15 信号傅里叶变换在matlab上遇到的小问题请求帮助
  • ¥15 保护模式-系统加载-段寄存器
  • ¥15 电脑桌面设定一个区域禁止鼠标操作
  • ¥15 求NPF226060磁芯的详细资料