如何解决@Synchronized似乎无法同步访问共享资源以进行对Spring Webserver的异步调用
我有一个SpringBoot Web服务器;在其上的一条路由,用于控制单例实例的状态。该路线通常由多个参与者调用,因此必须进行同步。
路由调用的相应方法为set()
:
@Synchronized
public fun <T> set(t: T) {
val incomingState = State.from(t)
if(incomingState == innerState){
return
}
change(incomingState)
}
@Synchronized
private fun change(newState: State){
this.stateAccessLock.lock()
SystemLog.logResourceLocking("HomeState",isLocked = true)
SystemLog.logHomeEvent("Changing HomeState from '${innerState.name}' to '${newState.name}'")
try {
Home.INSTANCE.EXTENSION.broadcastStateChange(
innerState?.name,newState.name
)
}
finally {
innerState = newState
Home.save()
stateAccessLock.unlock()
SystemLog.logResourceLocking("HomeState",isLocked = false)
}
}
在使用@Synchronized注释之前,我还尝试在同一类中使用ReentrantLock
(如您所见,到目前为止,我忽略了将其删除)。初始化如下:
private var stateAccessLock = ReentrantLock()
@Autowired
fun HomeState(@Qualifier("stateAccessLock") stateAccessLock: ReentrantLock) {
this.stateAccessLock = stateAccessLock
}
现在,change()
中的第三行和最后一行记录了资源蜂鸣被锁定并被释放的情况。过滤这些事件的日志文件可以给我以下信息:
[2020-10-09T16:07:01.709] LOCK: Resource locked
[2020-10-09T16:07:01.710] LOCK: Resource locked
[2020-10-09T16:07:01.725] LOCK: Resource locked
[2020-10-09T16:07:01.727] LOCK: Resource locked
[2020-10-09T16:07:01.818] LOCK: Resource unlocked
[2020-10-09T16:07:01.828] LOCK: Resource unlocked
[2020-10-09T16:07:01.829] LOCK: Resource unlocked
[2020-10-09T16:07:01.839] LOCK: Resource unlocked
[2020-10-09T16:11:33.499] LOCK: Resource locked
[2020-10-09T16:11:33.523] LOCK: Resource locked
[2020-10-09T16:11:33.525] LOCK: Resource locked
[2020-10-09T16:11:33.692] LOCK: Resource unlocked
[2020-10-09T16:11:33.692] LOCK: Resource unlocked
[2020-10-09T16:11:33.693] LOCK: Resource unlocked
[2020-10-09T16:11:35.881] LOCK: Resource locked
[2020-10-09T16:11:35.959] LOCK: Resource unlocked
很明显,我想要这样的东西:
[2020-10-09T16:07:01.709] LOCK: Resource locked
[2020-10-09T16:07:01.710] LOCK: Resource unlocked
[2020-10-09T16:07:01.725] LOCK: Resource locked
[2020-10-09T16:07:01.727] LOCK: Resource unlocked
[2020-10-09T16:07:01.818] LOCK: Resource locked
[2020-10-09T16:07:01.828] LOCK: Resource unlocked
[2020-10-09T16:07:01.829] LOCK: Resource locked
[2020-10-09T16:07:01.839] LOCK: Resource unlocked
我错过了什么? 预先感谢!
解决方法
由于您没有从这些方法中返回任何内容,因此我将改为进行线程限制并完全放弃锁定。这还将确保您不会陷入僵局:
private val executor = Executors.newSingleThreadExecutor()
fun <T> set(t: T) {
executor.submit {
val incomingState = State.from(t)
if (incomingState == innerState) {
return
}
change(incomingState)
}
}
由于您具有单线程执行器,因此可以确保以串行方式(不锁定)处理请求。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。