Pedantically, it's defined behavior, and doesn't use an interpreter lock.
Granted, I'm completely head over heels for Rust, and I agree completely that ConcurrentModificationException is a crappy answer, but it is defined behavior (AFAIK).
It's not defined. The library/VM is very good at throwing ConcurrentModificationException in practice, but it's specified as a best-effort thing, not to be relied upon.
It's true that throwing exceptions is defined behavior, but it's not defined in a way you'd actually want to use. For your actual purposes, it's undefined.