Я знаю, что вы уже приняли другие ответы, но третьим вариантом будет использование класса AtomicReference пакета java.util.concurrent.atomic. Это обеспечивает операции поиска, обновления и сравнения, которые действуют атомарно, без необходимости какого-либо вспомогательного кода. Итак, в вашем примере:
public void render()
{
AtomicReference<MouseBallClass> mouseBall = ...;
// ... rendering various objects
MouseBall tmpBall = mouseBall.get();
if (tmpBall != null) tmpBall.draw();
}
Это выглядит очень похоже на решение Грега, и концептуально они похожи в том, что за кулисами оба используют волатильность, чтобы обеспечить свежесть значений, и делают временную копию для применения условия перед использованием значения.
Следовательно, точный пример, использованный здесь, не так хорош для демонстрации силы AtomicReferences. Вместо этого учтите, что ваш другой поток обновит переменную mouseball, только если она уже была нулевой - полезная идиома для различных блоков кода стиля инициализации. В этом случае обычно необходимо использовать синхронизацию, чтобы гарантировать, что если вы проверили и обнаружили, что шар был нулевым, он все еще будет нулевым, когда вы попытаетесь установить его (иначе вы вернетесь царства вашей первоначальной проблемы). Однако с AtomicReference вы можете просто сказать:
mouseBall.compareAndSet(null, possibleNewBall);
, потому что это атомарная операция, поэтому, если один поток «видит» значение как нулевое, он также установит для него ссылку возможногоNewBall, прежде чем другие потоки смогут его прочитать.
Еще одна приятная идиома с атомарными ссылками - если вы безоговорочно устанавливаете что-то, но должны выполнить какую-то очистку со старым значением. В этом случае вы можете сказать:
MouseBall oldBall = mouseBall.getAndSet(newMouseBall);
// Cleanup code using oldBall
AtomicIntegers имеют эти преимущества и многое другое; Метод getAndIncrement () прекрасно подходит для глобально используемых счетчиков, поскольку вы можете гарантировать, что каждый вызов этого метода будет возвращать определенное значение, независимо от чередования потоков. Резьба безопасности с минимумом суеты.