问题产生:
最近使用 ReentrantLock 在批处理代码中的时候,发现应该更新的1000+条数据中,只有2条成功更新了,百思不得其解,后来查询日志得知报了一个错 IllegalMonitorStateException ,问了度娘,解释为当前的线程不是此对象监视器的所有者。也就是要在当前线程锁定对象,才能用锁定的对象此行这些方法,像notify(),notifyAll()方法了,导致某一个线程调用了了另一个线程的这个方法;当时我就晕了,这个不是当使用 synchronized 的时候才有的方法吗???
问题解决:
于是乎仔细打断点排查代码问题,发现了一个致命的错误,就是在使用 ReentrantLock 时,我的代码块如下
private final ReentrantLock lock = new ReentrantLock();
public void batchSaveOrUpdate( List<OrganBusinessDetail> list){
OrganDetailSearchDAO organDetailSearchDAO = DAOFactory.getDAO(OrganDetailSearchDAO.class);
lock.lock();
for (OrganBusinessDetail organBusinessDetail : list) {
try {
中间省略;
}catch (Exception e){
e.printStackTrace();
}finally { lock.unlock(); }
想必看到这里错误已经很明显了,在lock.lock();执行后,当前线程锁定,执行完第一次循环后,lock.unlock();解除锁定,然后第二次执行循环时,由于lock.lock();不在循环体内,此时并木有锁定。。。所以导致最后lock.unlock()直接报错了。
仅此记录自己愚蠢的一次问题