In a multi-threaded environment, there’s always a risk of data being altered concurrently by multiple threads. There’re certainly numerous ways of preventing this from happening. The Java language has its own mechanisms to prevent this issue. To prevent concurrent access, we could use data structures that are synchronized. By being synchronized, it just meant that access to the data structure itself is done in a synchronized manner.
Some examples of synchronized data structures are: Vector, Hashtable & StringBuffer. There’s two sides to the story. With synchronized access, you get penalties on scalability and speed. Granted, there’re arguments that with the newer JVM and increase in CPU speed and memory, the performance (speed) issue isn’t that significant. But there’s always the scalability issue to consider.
But things aren’t so simple between Hashtable & HashMap. Their differences do not stop at being synchronized and unsynchronized. Hashtable does not allow for null keys nor values. HashMap on other hand, allows for both.
Other than synchronizing at data structure level, we could do so on the method or block-of-codes level. These are more recommended. In a situation whereby your data structure can be accessed in a single-thread and multi-thread environment, you could have two methods (synchronized and unsynchronized) accessing the same data structure.
For reusability reason, synchronized methods are preferred over synchronized statements.