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();之后就可以了。

    评论

报告相同问题?

悬赏问题

  • ¥50 易语言把MYSQL数据库中的数据添加至组合框
  • ¥20 求数据集和代码#有偿答复
  • ¥15 关于下拉菜单选项关联的问题
  • ¥20 java-OJ-健康体检
  • ¥15 rs485的上拉下拉,不会对a-b<-200mv有影响吗,就是接受时,对判断逻辑0有影响吗
  • ¥15 使用phpstudy在云服务器上搭建个人网站
  • ¥15 应该如何判断含间隙的曲柄摇杆机构,轴与轴承是否发生了碰撞?
  • ¥15 vue3+express部署到nginx
  • ¥20 搭建pt1000三线制高精度测温电路
  • ¥15 使用Jdk8自带的算法,和Jdk11自带的加密结果会一样吗,不一样的话有什么解决方案,Jdk不能升级的情况