Hashtable: why is get method synchronized?
Asked Answered
C

3

6

I known a Hashtable is synchronized, but why its get() method is synchronized?

Is it only a read method?

Concoction answered 14/1, 2013 at 1:40 Comment(3)
Because it needs to be synchronized with the put methods.Recurrent
I don't understannd.There is only one class field--table need synchronized,but get method no write operation?Concoction
Both the put and get operations have to be synchronized with each other...and they are.Bemis
D
16

If the read was not synchronized, then the Hashtable could be modified during the execution of read. New elements could be added, the underlying array could become too small and could be replaced by a bigger one, etc. Without sequential execution, it is difficult to deal with these situations.

However, even if get would not crash when the Hashtable is modified by another thread, there is another important aspect of the synchronized keyword, namely cache synchronization. Let's use a simplified example:

class Flag {
  bool value;

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

set is synchronized, but get isn't. What happens if two threads A and B simultaneously read and write to this class?

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

Is it guaranteed at step 3 that A sees the modification of thread B?

No, it isn't, as A could be running on a different core, which uses a separate cache where the old value is still present. Thus, we have to force B to communicate the memory to other core, and force A to fetch the new data.

How can we enforce it? Everytime, a thread enters and leaves a synchronized block, an implicit memory barrier is executed. A memory barrier forces the cache to be updated. However, it is required that both the writer and the reader have to execute the memory barrier. Otherwise, the information is not properly communicated.

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

Deathless answered 14/1, 2013 at 2:54 Comment(0)
G
1

Have a look in Hashtable source code and you can think of lots of race conditions that can cause problem in a unsynchronized get() .

(I am reading JDK6 source code)

For example, a rehash() will create a empty array, and assign it to the instance var table, and put the entries from old table to the new one. Therefore if your get occurs after the empty array assignment, but before actually putting entries in it, you cannot find your key even it is in the table.

Another example is, there is a loop iterate thru the linked list at the table index, if in middle in your iteration, rehash happens. You may also failed to find the entry even it exists in the hashtable.

Ganymede answered 14/1, 2013 at 2:32 Comment(1)
I agree with you,but I am not sure,so ask.Concoction
E
0

Hashtable is synchronized meaning the whole class is thread-safe

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

A read method must be synchronized as a write method because it will make sure the visibility and the consistency of the variable.

Expressway answered 14/1, 2013 at 2:12 Comment(2)
This is nonsensical. Hashtable is a class and you can't declare a class to be synchronized. And indeed, Hashtable is not entirely thread-safe. (In particular, iteration is not thread-safe in the way that you might expect ...)Compose
@StephenC I agree with what you said after reading thread-safe Thanks!Expressway

© 2022 - 2024 — McMap. All rights reserved.