https://kotlinlang.org logo
a

angarron

03/19/2020, 4:34 PM
argghhh I have a CME in my app that I can't quite understand -- would greatly appreciate any help! I have this code (simplified a bit):
Copy code
@Synchronized
fun notify(updates: Set<UpdateSource>) {
  Log.d("findme", "notify START: $updates")
  observers.forEach { observer ->
    /* stuff */
  }
  Log.d("findme", "notify END")
}

@Synchronized
private fun disconnect(observer: Observer) {
  Log.d("findme", "disconnect START")
  observers.remove(observer)
  Log.d("findme", "disconnect END")
}
and I see these logs:
Copy code
2020-03-19 09:25:16.545 21962-22072/com.discord.debug D/findme: notify START: [com.discord.stores.StoreUser@c7528b5, com.discord.stores.StoreUser$Companion$UsersUpdate$1@91882e5]
2020-03-19 09:25:16.548 21962-22072/com.discord.debug D/findme: disconnect START
2020-03-19 09:25:16.548 21962-22072/com.discord.debug D/findme: disconnect END
Can anyone explain how it's possible that "notify END" never prints? if that
forEach
was hanging, I would expect a hung thread, but we are able to enter the
disconnect
method -- which means that I feel like I'm misunderstanding something about
@Synchronized
a

araqnid

03/19/2020, 4:42 PM
is notify invoking something that is then invoking disconnect() on the same thread? monitors are re-entrant, i.e. one thread can keep re-entering synchronized methods and it just increases an internal counter and unlocks at the end
that would explain CME (= ConcurrentModificationException, I assume)
for something like an observer list, I’d usually use CopyOnWriteArrayList to avoid it
a

angarron

03/19/2020, 4:45 PM
yup im pretty sure I have something calling disconnect, that makes sense. thanks!
p

pedro

03/19/2020, 4:45 PM
I assume something in the for loop inside
notify
called
disconnect
. You never saw the “END” log because the exception was thrown. The stacktrace would be something like 1. notify 2. disconnect so the notify method had not finished yet