Во-первых, ваш Counter
класс бессмысленен.Метод updateCounter
не обновляется, он возвращает новый объект.Так что просто удалите класс Counter
и используйте long
в вашем CounterService
.
. Тогда остается вопрос, для чего предназначен CounterService
.Это просто заворачивает долго.
Но не обращая на это внимания.Нет - вы не можете написать тест, чтобы доказать, что что-то не является потокобезопасным, поскольку проблемы многопоточности не являются детерминированными.Вы можете вставить задержки в места, где вы знаете, что могут возникнуть условия гонки, но это работает только в том случае, если вы уже знаете, что оно не является поточно-ориентированным в конкретном месте, и вы хотите это доказать.Но если вы не знаете, в чем проблема, вы не сможете вставить задержки в нужное место, чтобы доказать, что возможная проблема действительно существует.
К тому же, вы не сможете доказать, чтоэто также верно, хотя вы можете увеличить свои шансы, вставляя сны между операциями, чтобы вызвать проблемы.Но это может не сработать, и вы не тестируете реальный сценарий.
Ваш тест не пройден, потому что вы не понимаете, что делает синхронизированный и что подразумевает потокобезопасность.
В вашемtest, вы устанавливаете значение счетчика и затем получаете его в следующей строке.Если вы синхронизируете set и get, все это означает, что отдельные операции get и set являются поточно-ориентированными.Это не означает, что вы можете вызывать get и set отдельно, и этот get возвращает то же значение, что и предыдущий набор.
Если вы хотите установить что-то, а затем безопасно вернуть то же значение, у вас естьчтобы обернуть вызовы get и set в синхронизированный блок.
synchonized(this) { // get must return same thing that was set
set
get
}
Я настоятельно рекомендую вам сосредоточиться на понимании того, чего должна достичь ваша программа и что означает безопасность потоков и синхронизация в этом контексте.В противном случае вы все равно не сможете разработать правильный тест.