The instance variable stop
needs to be volatile, otherwise there's no guarantee the other threads will see changes to it. There are a lot of conflicting interests at work: threads want a consistent view of the program state, CPUs want to be able to cache data, the JVM wants to be able to reorder instructions. Making the instance variable volatile means that it can't be cached and that happens-before relationships are established that limit instruction reordering.
See this other answer (+1) for a good example of what reordering may happen without marking the variable volatile.
(By the way using interruption for thread cancellation is preferable to using an instance variable.)