Я думаю, что вы путаете термины "потокобезопасный" и "атомарный". Они не означают одно и то же. Метод может быть потокобезопасным, не будучи атомарным, и может быть атомарным (для одного потока), не будучи потокобезопасным.
Потокобезопасный - это резиновый термин, который трудно определить, не будучи круглым. Согласно Гетцу, хорошей рабочей моделью является то, что метод является поточно-ориентированным, если он «так же корректен» при использовании в многопоточном контексте, как и в однопоточном контексте. Резинность заключается в том, что правильность субъективна, если только у вас нет формальной спецификации для сравнения.
Напротив, атомарный легко определить. Это просто означает, что операция либо происходит полностью, либо вообще не происходит.
Итак, ответ на ваш вопрос заключается в том, что drainTo()
является потокобезопасным, но не атомарным. Это не атомарно, потому что оно может вызвать исключение на полпути через слив. Однако по модулю очередь все еще будет в согласованном состоянии, независимо от того, выполняли ли другие потоки какие-либо действия в очереди в одно и то же время.
(В приведенном выше обсуждении подразумевается, что конкретная реализация интерфейса BlockingQueue
правильно реализует интерфейс. Если нет, все ставки отключены.)