Обычно, если безопасность потока является серьезной проблемой, я бы избегал любой из этих опций.
Гораздо лучшим вариантом, как правило, является сохранение вашей собственной закрытой переменной и блокировка ее во всех методах, где это требуется, включая весь общедоступный API, который обращается к коллекции.
Реальная опасность заключается в том, что, блокируя тип, который открыт или может быть открыт для внешнего мира, вы потенциально открываете возможность для «внешнего мира» связываться с вашей синхронизацией. Если используется более одной блокировки, это может привести к мертвым блокировкам (если внешняя блокировка на что-то, чего вы не ожидаете).
Создавая личную переменную и блокируя ее исключительно, вы «контролируете» ситуацию. Это делает намного более ясным, что происходит. Кроме того, он облегчает синхронизацию между несколькими объектами, особенно позже, когда вы поддерживаете код, поскольку блокировка очень проста.