Actually, lots of ways:
- No need for synchronization at all if you don't have mutable state.
- No need for synchronization if the mutable state is confined to a single thread. This can be done by using local variables or
java.lang.ThreadLocal
. - You can also use built-in synchronizers.
java.util.concurrent.locks.ReentrantLock
has the same functionality as the lock you access when usingsynchronized
blocks and methods, and it is even more powerful.