重写 ConcurrentHashMap compute() 和 computeIfPresent()
Rewrite ConcurrentHashMap compute() and computeIfPresent()
ConcurrentHashMap 的实现非常复杂,因为它专门设计用于允许并发可读性,同时最大限度地减少更新争用。在非常高的抽象层次上,它被组织为一个分桶哈希 table.
在移动应用程序的上下文中,ConcurrentHashMaps 的一个问题是 compute() 和 computeIfPresent() 等函数需要 API 24 (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N)
我想知道如何满足较低级别的设备,如何重写 compute() 和 computeIfPresent() 以应用于 API23 及以下设备?
以下是我使用这些函数的一些情况。
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) {
scheduledTasks.compute(uid) { _, oldTask ->
val newTask = ScheduledTask(uid, runnable, interval, null)
if (oldTask != null) {
oldTask.cancel()
requiresRestart.set(oldTask.isScheduled)
}
newTask
}
} else {
// TODO Need lower API implementation
}
在上面的示例中,我正在更新 scheduledTasks,它是一个 ConcurrentHashMap。可以创建跨多个线程的多个计划任务。
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) {
return scheduledTasks.computeIfPresent(uid) { _, oldTask ->
val future = executor.scheduleWithFixedDelay(
oldTask.runnable, 0, oldTask.interval.toLong(), TimeUnit.SECONDS)
ScheduledTask(oldTask.uid, oldTask.runnable, oldTask.interval, future)
}
} else {
// TODO Need lower API implementation
return null
}
我只会给出 computeIfPresent
的示例,因为 compute
非常相似,只是需要更多的工作。这是在Java;转换为 Kotlin 并没有什么特别的区别。
public <K, V> V computeIfPresent(
ConcurrentMap<K, V> map, K key, BiFunction<? super K, ? super V, ? extends V> f) {
V currentValue = map.get(key);
while (currentValue != null) {
V nextValue = f.apply(key, currentValue);
if (nextValue == null) {
if (map.remove(key, currentValue)) {
return currentValue;
}
} else if (map.replace(key, currentValue, nextValue)) {
return currentValue;
}
currentValue = map.get(key);
}
return null;
}
此版本具有适当的原子性保证。
ConcurrentHashMap 的实现非常复杂,因为它专门设计用于允许并发可读性,同时最大限度地减少更新争用。在非常高的抽象层次上,它被组织为一个分桶哈希 table.
在移动应用程序的上下文中,ConcurrentHashMaps 的一个问题是 compute() 和 computeIfPresent() 等函数需要 API 24 (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N)
我想知道如何满足较低级别的设备,如何重写 compute() 和 computeIfPresent() 以应用于 API23 及以下设备?
以下是我使用这些函数的一些情况。
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) {
scheduledTasks.compute(uid) { _, oldTask ->
val newTask = ScheduledTask(uid, runnable, interval, null)
if (oldTask != null) {
oldTask.cancel()
requiresRestart.set(oldTask.isScheduled)
}
newTask
}
} else {
// TODO Need lower API implementation
}
在上面的示例中,我正在更新 scheduledTasks,它是一个 ConcurrentHashMap。可以创建跨多个线程的多个计划任务。
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) {
return scheduledTasks.computeIfPresent(uid) { _, oldTask ->
val future = executor.scheduleWithFixedDelay(
oldTask.runnable, 0, oldTask.interval.toLong(), TimeUnit.SECONDS)
ScheduledTask(oldTask.uid, oldTask.runnable, oldTask.interval, future)
}
} else {
// TODO Need lower API implementation
return null
}
我只会给出 computeIfPresent
的示例,因为 compute
非常相似,只是需要更多的工作。这是在Java;转换为 Kotlin 并没有什么特别的区别。
public <K, V> V computeIfPresent(
ConcurrentMap<K, V> map, K key, BiFunction<? super K, ? super V, ? extends V> f) {
V currentValue = map.get(key);
while (currentValue != null) {
V nextValue = f.apply(key, currentValue);
if (nextValue == null) {
if (map.remove(key, currentValue)) {
return currentValue;
}
} else if (map.replace(key, currentValue, nextValue)) {
return currentValue;
}
currentValue = map.get(key);
}
return null;
}
此版本具有适当的原子性保证。