Lifecycle callbacks can be registered while another thread dispatches them, risking races and iterator invalidation. Snapshot shared callback objects under a mutex, then invoke them unlocked to preserve reentrancy and mutable callback state.