I know you've already accepted other answers, but a third option would be to use the java.util.concurrent.atomic package's AtomicReference class. This provides retrieval, update and compare operations that act atomically without you needing any supporting code. So in your example:
public void render()
{
AtomicReference<MouseBallClass> mouseBall = ...;
// ... rendering various objects
MouseBall tmpBall = mouseBall.get();
if (tmpBall != null) tmpBall.draw();
}
This looks very similar to Greg's solution, and conceptually they are similar in that behind the scenes both use volatility to ensure freshness of values, and take a temporary copy in order to apply a conditional before using the value.
Consequently the exact example used here isn't that good for showing the power of the AtomicReferences. Consider instead that your other thread will update the mouseball vairable only if it was already null - a useful idiom for various initialisation-style blocks of code. In this case, it would usually be essential to use synchronization, to ensure that if you checked and found the ball was null, it would still be null when you tried to set it (otherwise you're back in the realms of your original problem). However, with the AtomicReference you can simply say:
mouseBall.compareAndSet(null, possibleNewBall);
because this is an atomic operation, so if one thread "sees" the value as null it will also set it to the possibleNewBall reference before any other threads get a chance to read it.
Another nice idiom with atomic references is if you are unconditionally setting something but need to perform some kind of cleanup with the old value. In which case you can say:
MouseBall oldBall = mouseBall.getAndSet(newMouseBall);
// Cleanup code using oldBall
AtomicIntegers have these benefits and more; the getAndIncrement() method is wonderful for globally shared counters as you can guarantee each call to it will return a distinct value, regardless of the interleaving of threads. Thread safety with a minimum of fuss.