Hashtable: why is the get method synchronized?

I know the Hashtable synchronized, but why is its get() method synchronized?

Is this just a reading method?

+6
source share
3 answers

If the read has not been synchronized, then the Hashtable can be modified while the read is in progress. New elements can be added, the base array can become too small and can be replaced with larger ones, etc. Without consistent execution, these situations are difficult to handle.

However, even if get does not fail when the Hashtable is modified by another thread, there is another important aspect of the synchronized , namely: cache synchronization. Let us use a simplified example:

 class Flag { bool value; bool get() { return value; } // WARNING: not synchronized synchronized void set(bool value) { this->value = value; } } 

set synchronized, but get not. What happens if two streams A and B are simultaneously read and written to this class?

 1. A calls read 2. B calls set 3. A calls read 

Is it guaranteed in step 3 that A sees a modification of thread B?

No, this is not so, since A can run on a different kernel that uses a separate cache, where the old value is still present. Thus, we are forced to B associate memory with another core and force A to retrieve new data.

How can we enforce it? Each time a thread enters and leaves a synchronized block, an implicit memory barrier is executed. A memory failure causes the cache to update. However, it is required that both the writer and the reader must fulfill the memory barrier. Otherwise, the information is not transmitted properly.

In our example, thread B already uses the synchronized set method, so its data modification is reported at the end of the method. However, A does not see the changed data. The solution is to do get synchronization, so it is forced to receive updated data.

+14
source

Take a look at the Hashtable source code and you can think of a variety of race conditions that can cause a problem in unsynchronized get() .

(I am reading the JDK6 source code)

For example, a rehash() will create an empty array and assign it to the var table instance and put the records from the old table into the new one. Therefore, if your get occurs after the empty assignment of the array, but before it is actually placed in it, you will not be able to find your key, even if it is in the table.

Another example is that a loop iterates through a linked list at the table index if there is a redirect in the middle of your iteration. You may also not find the entry, even if it exists in the hash table.

+1
source

Hashtable synchronized, which means the whole class is thread safe

Inside the Hashtable not only the get () method is synchronized, but also many other methods. And especially the put () method is synchronized, as Tom said.

The read method must be synchronized as a write method, as it will ensure the visibility and consistency of the variable.

0
source

All Articles