我想问一下锁定机制。假设我想做一些类似“非常简单的数据库”的事情。我有3个Map,一个用于存储值,另外两个用于存储“按用户”和“按设备”的索引,这样通过两者进行过滤会更有效。我不想在这三个Map之间有不一致,因为几乎所有的方法都是用2个或所有的Map来操作的,所以需要同步,并且并发Map类型是不够的。
问:可以将synchronized(this)与synchronized(userIdIndices)混合使用吗?或者我需要在任何地方使用 this?如果线程进入例如 addDataPoint() 方法,synchronized(this)是否也会锁定 getUserIdIndicesSize() synchronized(userIdIndices),比如说一些更高阶的锁定,或者这些是完全独立的锁定,它将启用并发访问。
@Component
class DatapointStore {
private val dataPoints = HashMap<DatapointKey, Double>()
private val userIdIndices = HashMap<Long, TreeSet<DatapointKey>>()
private val deviceIdIndices = HashMap<Long, TreeSet<DatapointKey>>()
fun getDataPointsSize() = synchronized(dataPoints) { dataPoints.size }
fun getUserIdIndicesSize() = synchronized(userIdIndices) { userIdIndices.size }
fun getDeviceIdIndicesSize() = synchronized(deviceIdIndices) { deviceIdIndices.size }
fun addDataPoint(dataPoint: DatapointRequest) {
synchronized(this) { ... }
}
fun filterByUserId(userId: Long): List<DatapointRequest> {
synchronized(this) { ... }
}
fun filterByDeviceId(deviceId: Long): List<DatapointRequest> {
synchronized(this) { ... }
}
fun deleteByUserId(userId: Long) {
synchronized(this) { ... }
}
fun deleteByDeviceId(deviceId: Long) {
synchronized(this) { ... }
}
}
我希望它是完全同步的,其中一个线程不能添加新的数据点,而另一个线程正在删除,过滤或检查大小,但我不介意检查 getUserIdIndicesSize(),而执行 filterByDeviceId()。这就是为什么我想混合两种类型的锁。
1条答案
按热度按时间dgtucam11#
两个对象互斥锁之间没有关系。
synchronized(this)
表示的锁与synchronized(dataPoints)
创建的锁是独立的锁,即使dataPoints
是this
的属性。如果你想在所有三个Map中进行原子更新,你需要使用一个共享互斥锁(如this
)来访问所有Map。