functionaldude
10/19/2017, 5:54 PMHashMap
which is only accessed and modified in a single coroutine context:
val pushNotificationGeneratorThread = newSingleThreadContext(name = "Push Notification Generator Thread")
suspend fun clear() = run(pushNotificationDispatcherThread) {
lastNotificationDates.clear()
}
suspend fun put(key: String, value: Any) = run(pushNotificationDispatcherThread) {
lastNotificationDates.put(key, value)
}
However sometimes I still get a ConcurrentModificationException
. In my understanding this should be threadsafe.java.util.ConcurrentModificationException
at java.util.HashMap$EntryIterator.next(HashMap.java:1471)
at java.util.HashMap$HashIterator.nextNode(HashMap.java:1437)
at xxx$startCleanupThread$1.doResume(PushModule.kt:114)
at java.util.HashMap$EntryIterator.next(HashMap.java:1469)
at kotlin.coroutines.experimental.jvm.internal.CoroutineImpl.resume(CoroutineImpl.kt:54)
at kotlinx.coroutines.experimental.CancellableContinuationImpl.afterCompletion(CancellableContinuation.kt:318)
at kotlinx.coroutines.experimental.JobSupport.completeUpdateState(Job.kt:426)
at kotlinx.coroutines.experimental.JobSupport.updateState(Job.kt:382)
at kotlinx.coroutines.experimental.AbstractCoroutine.resume(CoroutineScope.kt:80)
at kotlinx.coroutines.experimental.CancellableContinuationImpl.resumeUndispatched(CancellableContinuation.kt:287)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:180)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.lang.Thread.run(Thread.java:748)
at kotlinx.coroutines.experimental.ResumeUndispatchedRunnable.run(Executors.kt:79)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
bj0
10/19/2017, 6:00 PMfunctionaldude
10/19/2017, 6:07 PMsuspend fun cleanup() = run(pushNotificationGeneratorThread) {
while (true) {
val tenSecondsAgo = Date()
delay(time = 10, unit = TimeUnit.SECONDS)
lastNotificationDates.forEach { (userId, dateMap) ->
dateMap.forEach { (payloadId, lastNotificationDate) -> remove() }
if (dateMap.isEmpty()) remove()
}
}
}
bj0
10/19/2017, 6:11 PMfunctionaldude
10/19/2017, 6:13 PMpushNotificationGeneratorThread
bj0
10/19/2017, 6:18 PMremove()
function do? does it modify the list?functionaldude
10/19/2017, 6:22 PMbj0
10/19/2017, 6:53 PMfunctionaldude
10/19/2017, 7:21 PM