mutual exclusion using Hashtable of java - java

hi mate i have a global Hashtable in my class, and two thread A and B that work with her.
A reads from HashTable and B write in Hashtable.. is there a problem of mutual exclusion ? i need to syncrhonize it or Hashtable class is safe ?

Hashtable is a thread-safe implementation of the Map interface.
In regular put and get operations you will be safe. However, when you will iterate on it in one thread and modify its contents from another thread, you will have ConcurrentModificationException issues. So, when iterating, make sure you iterate on a copy of the original Hashtable.

You should use ConcurrentHashMap instead, which is a much better/faster implementation of java.util.Map interface.

It's useful to use a synchronized HashMap offered by java collections. This class is a simple wrapper and encapsulates the hashmap :
Collections.synchronizedMap(new HashMap());
Further example example is in the java docs :
http://docs.oracle.com/javase/1.4.2/docs/api/java/util/Collections.html synchronizedMap

HashTable gaurantees that any operation executed on it is atomic. but If you are executing multiple operations you should synchronize them. In below example even if contains and put are atomic but the code has a check and act raise condition so you need additional synchronization for this.
if(!hashtable.contains(Object))
{
hashtable.put(key, value);
}
Also check Collections.synchronizedMap() or ConcurrentHashMap rather than HashTable

Everyone has said what can be said but this is just to complement with regards to what you call mutual exclusion. You are asking if there won't be such a problem. A thread-safe program must ensure that that if threadA is using say a block of code block1 no other thread will access it until the thread is done. So, if I understand well what you mean by mutual exclusion, yes threads accessing the same synchronized (thread-safe) shared resource are mutually exclusive because they both can't access it at the same time.
Java practically does much of the hard for you if you choose one of the proposed safe Map implementation. Now if your Hashtable ( or whatever else thread-safe mao you prefer ) is a shared resource, the only thing you need to take care of is the happens-before relation. It will be important if one thread is reading data and the other writing data.
More can be found at java concurrency tutorial and java concurrent package docs

Related

ConcurrentHashMap and compound operations

Hashtable and Collections.synchronizedMap are thread safe but still compound operations like
if (!map_obj.containsKey(key)) {
map_obj.put(key, value);
}
needs external synchronization as:
synchronized(map_obj) {
if (!map_obj.containsKey(key)) {
map_obj.put(key, value);
}
}
Suppose we have ConcurrentHashMap(CHM) instead of Hashtable or HashMap. CHM provides an alternative putIfAbsent() method for the above compound operation, thus removing the need of external synchronization.
But suppose there is no putIfAbsent() provided by CHM. Then can we write following code:
synchronized(concurrenthashmap_obj) {
if (!concurrenthashmap_obj.containsKey(key)) {
concurrenthashmap_obj.put(key, value);
}
}
I mean can we use external synchronization on CHM object?Will it work?
For above compound operation there is putIfAbsent() method in CHM but how can we achieve thread safety for other compound operations if we are using CHM. I mean can we use external synchronization on CHM object?
No, you cannot use external synchronization to ensure atomicity of compound operations over ConcurrentHashMap.
To be precise, you can use external synchronization to ensure atomicity of compound operations, but only if all operations with ConcurrentHashMap are synchronized over the same lock as well (though use of ConcurrentHashMap won't make sense in this case - you can replace it with regular HashMap).
Approach with external synchronization works with Hashtable and Collections.synchronizedMap() only because they guarantee that their primitive operations are synchronized over these objects as well. Since ConcurrentHashMap doesn't provide such a guarantee, primitive operations may interfere with execution of your compound operations, breaking their atomicity.
However, ConcurrentHashMap provides number of methods that can be used to implement compound operations in optimistic manner:
putIfAbsent(key, value)
remove(key, value)
replace(key, value)
replace(key, oldValue, newValue)
You can use these operation to implement certain compound operations without explict synchronization, the same way as you would do for AtomicReference, etc.
There isn't any reason why you can't. Traditional synchronization works with everything, there aren't special exceptions against them. ConcurrentHashMaps simply use more optimized thread-safety mechanisms, if you wish to do something more complex, falling back to traditional synchronization may actually be your only option (that and using locks).
You can always use a synchronized block. The fancy collections in java.util.concurrent do not prohibit it, they just make it redundant for most common use cases. If you are performing a compound operation (e.g. - you want to insert two keys which must always have the same value), not only can you use external synchronization - you must.
E.g.:
String key1 = getKeyFromSomewhere();
String key2 = getKeyFromSomewhereElse();
String value = getValue();
// We want to put two pairs in the map - [key1, value] and [key2, value]
// and be sure that in any point in time both key1 and key2 have the same
// value
synchronized(concurrenthashmap_obj) {
concurrenthashmap_obj.put(key1, value);
// without external syncronoziation, key1's value may have already been
// overwritten from a different thread!
concurrenthashmap_obj.put(key2, value);
}
As the ConcurrentHashMap implements the Map Interface, it does support all features every basic Map does as well. So yes: you can use it like any other map and ignore all the extra features. But then you will essentially have a slower HashMap.
The main difference between a synchronized Map and a concurrent Map is - as the name says - concurrency. Imagine you have 100 threads wanting to read from the Map, if you synchronize you block out 99 threads and 1 can do the work. If you use concurrency 100 threads can work at the same time.
Now if you think about the actual reason why you use threads, you soon come to the conclusion that you should get rid of every possible synchronized block that you can.
It all depends on what you mean by "other compound operation" and by "working". Synchronization works with ConcurrentHashMap exactly the same way as it works with any other object.
So, if you want some complex shared state change to be seen as an atomic change, then all accesses to this shared state must be synchronized, on the same lock. This lock could be the Map itself, or it could be another object.
About java.util.concurrent.ConcurrentHashMap
"is fully interoperable with Hashtable in programs that rely on its thread safety but not on its synchronization details: they do not throw ConcurrentModificationException."
"allows concurrency among update operations"
About java memory
Generally speaking the reads are safe from a synchronization standpoint but not a memory standpoint.
See also "http://www.ibm.com/developerworks/java/library/j-jtp03304/".
So synchronizaton and volatile should be used to manage concurrent reading (vs. writing).
About putIfAbsent
putIfAbsent is your friend:
If the specified key is not already associated with a value, associate
it with the given
value. This is equivalent to
if (!map.containsKey(key))
return map.put(key, value);
else
return map.get(key);
except that the action is performed !!!atomically!!!.

EnumMap with concurrent put/get

I am considering using EnumMap in a concurrent environment. However, the environment is atypical, here's why:
EnumMap is always full: there are no unmapped keys when the map is exposed to the concurrent environment
Only put() and get() operations will be used (no iterating over, no remove(), etc.)
It is completely acceptable if a call to get() does not reflect a call to put() immediately or orderly.
From what I could gather, including relevant method source code, this seems to be a safe scenario (unlike if iterations were allowed). Is there anything I might have overlooked?
In general, using non-thread-safe classes across threads is fraught with many problems. In your particular case, assuming safe publication after all keys have had values assigned (such that map.size() == TheEnum.values().length), the only problem I can see from a quickish glance of EnumMap's code in Java 1.6 is that a put may not ever get reflected in another thread. But that's only true because of the internals of EnumMap's implementation, which could change in the future. In other words, future changes could break the use case in more dangerous, subtle ways.
It's possible to write correct code that still contains data races -- but it's tricky. Why not just wrap the instance in a Collections.synchronizedMap?
Straight from the JavaDoc:
Like most collection implementations EnumMap is not synchronized. If multiple threads access an enum map concurrently, and at least one of the threads modifies the map, it should be synchronized externally. This is typically accomplished by synchronizing on some object that naturally encapsulates the enum map. If no such object exists, the map should be "wrapped" using the Collections.synchronizedMap(java.util.Map<K, V>) method. This is best done at creation time, to prevent accidental unsynchronized access:
Map<EnumKey, V> m = Collections.synchronizedMap(new EnumMap<EnumKey, V>(...));
The problem you have is that threads may not ever see the change made by another thread or they may see partially made changes. It's the same reason double-check-locking was broken before java 5 introduced volatile.
It might work if you made the EnumMap reference volatile but I'm not 100% sure even then, you might need the internal references inside the EnumMap to be volatile and obviously you can't do that without doing your own version of EnumMap.

Is java.util.Hashtable thread safe?

It's been a while since I've used hashtable for anything significant, but I seem to recall the get() and put() methods being synchronized.
The JavaDocs don't reflect this. They simply say that the class Hashtable is synchronized. What can I assume? If several threads access the hashtable at the same time (assuming they are not modifying the same entry), the operations will succeed, right? I guess what I'm asking is "Is java.util.Hashtable thread safe?"
Please Guide me to get out of this issue...
It is threadsafe because the get, put, contains methods etc are synchronized. Furthermore, Several threads will not be able to access the hashtable at the same time, regardless of which entries they are modifying.
edit - amended to include the provisio that synchronization makes the hashtable internally threadsafe in that it is modified atomically; it doesn't guard against race conditions in outside code caused by concurrent access to the hashtable by multiple threads.
For general usage it is thread safe.
But you have to understand that it doesent make your application logic around it thread-safe. For e.g. consider implementing to put a value in a map, if its not there already.
This idiom is called putIfAbsent. Its difficult to implement this in a thread-safe manner using HashTable alone. Similarly for the idiom replace(k,V,V).
Hence for certain idioms like putIfAbsent and and replace(K,V,V), I would recommend using ConcurrentHashMap
Hashtable is deprecated. Forget it. If you want to use synchronized collections, use Collections.syncrhonize*() wrapper for that purpose. But these ones are not recommended. In Java 5, 6 new concurrent algorithms have been implemented. Copy-on-write, CAS, lock-free algorithms.
For Map interface there are two concurrent implementations. ConcurrentHashMap (concurrent hash map) and ConcurrentSkipListMap - concurrent sorted map implementaion.
The first one is optimized for reading, so retrievals do not block even while the table is being updated. Writes are also work much faster comparing with synchronized wrappers cause a ConcurrentHashMap consists of not one but a set of tables, called segments. It can be managed by the last argument in the constructor:
public ConcurrentHashMap(int initialCapacity,
float loadFactor,
int concurrencyLevel);
ConcurrentHashMap is indispensable in highly concurrent contexts, where it performs far better than any available alternative.
No. It is 'threadsafe' only to the extent that its methods are synchronized. However it is not threadsafe in general, and it can't be, because classes that export internal state such as Iterators or Enumerations require the use of the internal state to be synchronized as well. That's why the new Collections classes are not synchronized, as the Java designers recognized that thread-safety is up to the user of the class, not the class itself.
I'm asking is "Is java.util.Hashtable thread safe?".
Yes Hashtable is thread safe, If a thread safe is not needed in your application then go through HashMap, In case, If a thread-safe implementation is desired,then it is recommended to use ConcurrentHashMap in place of Hashtable.
Note, that a lot of the answers state that Hashtable is synchronised. but this will give you a very little. The synchronization is on the accessor / mutator methods will stop two threads adding or removing from the map concurrently, but in the real world you will often need additional synchronisation.
Even iterating over a Hashtable's entries is not thread safe unless you also guard the Map from being modified through additional synchronization.
If you look into Hashtable code, you will see that methods are synchronized such as:
public synchronized V get(Object key)
public synchronized V put(K key, V value)
public synchronized boolean containsKey(Object key)
You can keep pressing on control key (command for mac) and then click on any method name in the eclipse to go to the java source code.
Unlike the new collection implementations, Hashtable is synchronized. *If a thread-safe implementation is not needed, it is recommended to use HashMap* in place of Hashtable. If a thread-safe highly-concurrent implementation is desired, then it is recommended to use ConcurrentHashMap in place of Hashtable.
http://download.oracle.com/javase/7/docs/api/java/util/Hashtable.html
Yes, Hashtable thread safe, so only one thread can access a hashtable at any time
HashMap, on the other side, is not thread safe (and thus 'faster').

synchronized vs lock vs synchronized map

I need to synchrozize my accesses to the hashmap.
Here are my options
I know I can use Synchronize keyword. this is one option. Can I use the map itself ?
currently I have a get method that if the object does not exists creates it and puts it in the map. I can synchronize the method.
I can use a syncronize block
I can use
Map m = Collections.synchronizedMap(new HashMap(...));
in my code.
I tend to do 4 cause it sounds the easiest. Any suggestions?
I would suggest that you don't make methods synchronized, and that you don't lock on the map itself. I generally prefer to use a separate locking object which is only used for locking and only known about in the class which owns the map.
You could potentially use synchronizedMap, but it depends what you want to do with it. If you only ever get and put values, then that's fine. If you ever need to iterate over the map, you need to block other threads from modifying the map while you're iterating.
Another option is to use a ConcurrentHashMap. See the docs for the semantics. This is probably the simplest approach if it behaves the way you need it to.
You could use ConcurrentHashMap.putIfAbsent() which may do what you want without synchronisation.

Java synchronization problem

I have two threads and one class.
Thread1 updates the local object of the class via 3 different methods.
The local object (behind the scene) uses some sort of ArrayList to store data.
Three methods (mentioned earlier), are doing something with elements of the list...
Thread2 queries the local object (content of array list).
PROBLEM:
How can I make sure that none of the three updating methods (Thread1) will modify the content of the "local object" while it's being read by Thread2?
Thanks
Put a common lock around portions of the code that modify the ArrayList using synchronized. It doesn't really matter what object you use as a lock, as long as it's the same, but I think using the ArrayList itself would be idiomatic:
synchronized (list) {
list.put()...
}
synchronized (list) {
list.get()...
}
You can make the methods which access the data (read or write) 'synchronized'.
In all methods mentionned above use a synchronized(your_list) { ... code ... } context, making the methods synchronized is a maybe to hard solution, blocks more than needed if you just want to protect the list and not the whole object.
Using synchronized keyword. You are dealing with problem known as critical sections
I suggest you read the Java Tutorial on Concurrency, in particular the section on synchronization. You have a straightforward case of synchronization.

Categories