java.lang.IllegalMonitorStateException: attempt to unlock lock, not locked by current thread by node id
需求:界面点击同步按钮,后台异步处理长时间任务。
设计:后端使用了分布式锁,确保多次点击,只会同步一次。但为了提示友好,在获取到锁的时候提示:同步任务提交成功。 而未获取到锁的时候提示:同步任务正在执行。
在接口请求线程中,我进行了lock.tryLock,然后在开启的异步线程中使用了lock.unlock,结果产生了java.lang.IllegalMonitorStateException: attempt to unlock lock, not locked by current thread。
解决方法也很明显,将lock和unlock都放到异步线程中。 但是异步线程是否获得锁这个状态怎么反馈给主线程。我想到的一个方式是主线程传入一个对象,异步线程修改这个对象,主线程获取对象值判断是否拿到锁(感觉有点蹩脚)。
如下代码:
AtomicInteger lockAquired = new AtomicInteger(-1);
// sync方法里开启的子线程会对lockAquired对象进行修改
someService.sync(productId, lockAquired);
//循环等待,直到lockAquired的值是否不等于初始值
//结果返回
if(lockAquired.get() == 1) {
return Result.ok("同步任务已发起,请稍后查询!", null);
} else {
return Result.ok("同步任务正在执行,请稍后再试!", null);
}
总结:纸上得来终觉浅。