Start here. This is the direct spoken answer to practice first.
Why this question matters
The safest synchronization strategy is often to reduce shared mutation. Read-heavy application state is a strong place to trade a coordinated write for simple and consistent reads.
I would build a complete new immutable routing table away from request threads, validate it, and then replace the shared reference in one coordinated operation. Each request captures the current reference and reads one stable version without taking a lock around every lookup. A failed refresh leaves the previous valid snapshot in place. This works well when updates are much less frequent than reads and the snapshot is affordable to rebuild.