Reputation: 71188
i need a thread safe map, i have something like this: (i'm very new to java)
public static class Manager
{
static
{
//something wrong here, doesn't compile
list = new java.util.Collections
.synchronizedMap(new Map<String, Client>());
}
static Map<String,Client> list;
public static void AddClient(Client client)
{
// thread safe add client to the list
}
public static void RemoveClient(Client client)
{
// thread safe remove client to the list
}
}
Upvotes: 53
Views: 86615
Reputation: 48258
from java.util.concurrent
ConcurrentHashMap<K,V>
ConcurrentMap<K,V>
ConcurrentNavigableMap<K,V>
ConcurrentSkipListMap<K,V>
from java.util.Collections
Collections.synchronizedMap(Map<K,V> m)
Collections.synchronizedNavigableMap(NavigableMap<K,V> m)
Collections.synchronizedSortedMap(SortedMap<K,V> m)
Upvotes: 1
Reputation: 338181
Java bundles a pair of interfaces for a concurrent Map
:
The first makes thread-safety and atomicity guarantees. The second adds those guarantees to NavigableMap
implementations that keep their keys in a certain order.
Java provides two classes that implement those interfaces. Third-party libraries may also provide classes implementing those interfaces. The classes bundled with Java are:
ConcurrentHashMap
(for ConcurrentMap
)ConcurrentSkipListMap
(for ConcurrentMap
and ConcurrentNavigableMap
)Example usage:
ConcurrentMap < Project , Person > map = new ConcurrentHashMap<>() ;
…and:
ConcurrentNavigableMap < Month , Person > map = new ConcurrentSkipListMap <>() ;
If an unmodifiable map works for you, see the Map.of
, Map.ofEntries
, and Map.copyOf
methods. Being unmodifiable brings thread-safe read-only access.
There is a legacy class, Hashtable
, that is generally not used anymore. But, for the sake of completeness, we should mention this class for its synchronized methods that provide thread-safety. To quote the JavaDoc:
If a thread-safe implementation is not needed, it is recommended to use
HashMap
in place ofHashtable
. If a thread-safe highly-concurrent implementation is desired, then it is recommended to useConcurrentHashMap
in place ofHashtable
.
Map
classesHere is a graphic table I made showing various characteristics of the various Map
implementations bundled with Java 11.
Look for the red boxes in the Concurrency column.
Upvotes: 2
Reputation: 29096
Your code should look like this, ignoring imports, et al.
public class Manager
{
Map<String,Client> list = java.util.Collections.synchronizedMap(new HashMap<String, Client>());
public void AddClient(Client client)
{
// thread safe add client to the list
}
public void RemoveClient(Client client)
{
// thread safe remove client to the list
}
}
That said, beware that this is not as thread safe as you might hope. As others have mentioned, you probably want to use the Java Concurrent Collections.
Upvotes: 2
Reputation: 182762
You can't initialize an object member variable in a static block. Static blocks are executed once when the class is first loaded, not once for every object of that class, whereas the variable "list" is created once for each object of the class.
Also, you can't instantiate a "new Map" because Map is an interface. You need to wrap the synchronizedMap around a real Map like a HashMap or a TreeMap.
{
list = new java.util.Collections
.synchronizedMap(new HashMap<String, Client>());
}
Upvotes: 1
Reputation: 570285
The ConcurrentHashMap
class from the java.util.concurrent
package is a thread-safe implementation of Map that offers far better concurrency than synchronizedMap
(and far superior scalability over Hashtable
). See http://www.ibm.com/developerworks/java/library/j-jtp07233.html.
Upvotes: 37
Reputation: 11708
Your map "list" needs to be static if you want to access it in a static block.
Upvotes: 1