jQuery in Action, 2nd edition*
The moose likes Threads and Synchronization and the fly likes Static variable is thread safe? Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » Threads and Synchronization
Bookmark "Static variable is thread safe?" Watch "Static variable is thread safe?" New topic
Author

Static variable is thread safe?

Gireesh Giri
Greenhorn

Joined: Apr 23, 2010
Posts: 23
Hi All,
I am using a static HashTable for multi thread model in java class, all the threads has to access the HashTable, is it will work fine?
Thanks in advance.
Mohamed Sanaulla
Saloon Keeper

Joined: Sep 08, 2007
Posts: 3068
    
  33

You would have to synchronize its access. As it is not thread safe .


Mohamed Sanaulla | My Blog
Nuwan Arambage
Ranch Hand

Joined: May 05, 2010
Posts: 76
yes definitely static variables are not thread safe.. you have to synchronize the block.... still totally correct.But my point of view , why static variable are not thread safe is the smart question.

Static variables are resides inside the method area.Method area is shared among all the threads in the particular JVM because of that you have to synchronize the code block to coordinate threads.



Thinker
Nuwan Arambage
Aditya Jha
Ranch Hand

Joined: Aug 25, 2003
Posts: 227

@Nuwan I'm not sure what exactly you meant here. Static variables are loaded along with loading of the class itself, without needing to create any 'Method' area.

As for the original question - Hashtable by itself is synchronized. So, if you are declaring a static final Hashtable and also intializing it at the time of declaration itself, all operations will be thread-safe on this Hashtable instance without you having to write any code for synchronization. If you're instantiating the Hashtable at a later point in time (and not with declaration), then there is a possibility that you need some amount of synchronization.

Also, consider using ConcurrentHashMap instead of Hashtable if you're using JDK 5 or above.
giridharan radhakrishnan
Greenhorn

Joined: Nov 26, 2008
Posts: 4


If multiple threads access the same hashmap you may result in concurrency exception and if you use hashtable we cannot say that multiple threads can access the same hashtable as it is synchronized. Try creating a static hashtable and create multiple threads to access the same hashtable it might throw exception but point at which it throws exception might vary each time when you run.
Try using ConcurrentHashMap<K,V> which is provided as part of JDK5 /6
Aditya Jha
Ranch Hand

Joined: Aug 25, 2003
Posts: 227

Try creating a static hashtable and create multiple threads to access the same hashtable it might throw exception but point at which it throws exception might vary each time when you run.


Nothing of this sort is gonna' happen. No exceptions will be raised. Hashtable is capable of handling simultaneous operations in different threads (which won't happen, technically, as it is synchronized).

I suggested ConcurrentHashMap for the simple reason of enhancing performance. The question of why the performance is better with ConcurrentHashMap as opposed to a Hashtable is beyond the scope of this question. for starters, I would recommend reading the JavaDoc for both classes.
Steve Luke
Bartender

Joined: Jan 28, 2003
Posts: 4181
    
  21

There is a bit more to consider for Hashtable synchronization as well. Single method calls on a Hashtable are synchronized, but that does not guarantee sequential consistency. So if you need successive operations to be performed in a safe manner you would need additional synchronization. One example of this would be iterating over the contents of the Hashtable (or even worse Enumerating over them). If one thread is iterating and another is modifying the Hashtable then the iteration can fail. If you are using enumerators you could be left with a mess.

Declaring the Hashtable as final doesn't solve this because it just prevents the reference variable from changing. It does not prevent the Hashtable being referenced from being modified. So with Hashtables, any multiple-access operations that require consistency between steps need to be synchronized.

An example that is often forgotten is the 'test - then add' paradigm. You test if a key or value is in the table, if it is there you modify the table and if it is not you add it with some default value. For example, you have code like this:

That wouldn't be thread safe, because the 'word' could be added to or removed from the list after the 'table.contains(word)' line is called, and before the conditional block is executed. Also, the value stored in the table for the word could change between the get and the put making the value you put into the table not correct.

Using ConcurrentHashMap fixes the problems with Iterators and Enumerators. It also fixes the first problem with the code above. It does not fix either of the problems with the above mentioned code, though.


Steve
Aditya Jha
Ranch Hand

Joined: Aug 25, 2003
Posts: 227

@Steve You raised a valid point. However, as you clearly mentioned, the problem you described can happen with ConcurrentHashMap too. In fact, it is much easier to resolve with Hashtable (a down point of ConcurrentHashMap, you could say).



The above code resolves the problem with Hashtable. However, if we need to do the same with a ConcurrentHashMap, things will be a little tricky. We'll have to use a 'Lock' instance, and share it across all classes which make use of the ConcurrentHashMap. Every single operation on this ConcurrentHashMap will have to be under that lock, in order to make the above operation atomic.

Gurus, please correct me if I'm wrong.
Steve Luke
Bartender

Joined: Jan 28, 2003
Posts: 4181
    
  21

You might want to try some more 'optimistic.' For example, you would use the putIfAbsent() method to add a value only if it didn't yet exist, and the replace(key, oldValue, newValue) to ensure you put the value back in only if it hasn't changed.



The optimistic approach doesn't always work (especially if there is a lot of modification to the list which would make the do{}while() loop have to repeat a lot). So be careful where you use it.

As for needing to pass the Lock around I have a couple of points:
1) I don't think you need to use a Lock, you could use normal synchronization just as you described above to handle it. You would need to synchronize all the modifications and methods that require sequential consistency that way - but simple single-step reads would still not need to be synchronized.
2) To prevent the need to pass a lock around you could force the centralization of modification of the Map, and any tasks which require sequential consistency. For example:

Here the Map is hidden inside the WordCounter class, private and hidden from being accessed from outside code. The methods can be called from lots of different threads. If you needed something to externally synchronize on you would roll that into your class and keep the content of the Map safe. You would publish read-only views of the Map if someone needed it...
Aditya Jha
Ranch Hand

Joined: Aug 25, 2003
Posts: 227

Fair enough! Thanks.

I wonder why the internal locking of ConcurrentHashMap is not exposed with some methods, so that one can actually do myMap.getReadLock().lock(), or similar. Would have been good, I guess.
Henry Wong
author
Sheriff

Joined: Sep 28, 2004
Posts: 18760
    
  40

Aditya Jha wrote:
I wonder why the internal locking of ConcurrentHashMap is not exposed with some methods, so that one can actually do myMap.getReadLock().lock(), or similar. Would have been good, I guess.


The implementation is incredibly optimistic -- there isn't any lock that will lock the whole map. The reads are pretty much all in parallel. And as for the writes, they are segmented, locking only a small section that this needed.


And quite frankly, the Map interface doesn't require this. And the only reason, IMHO, that HashTable exposes the lock, is because the iterator may not work without it. This is not an issue with the ConcurrentHashMap -- iterators work and provide a view at the time of creation.

Henry

Books: Java Threads, 3rd Edition, Jini in a Nutshell, and Java Gems (contributor)
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Static variable is thread safe?