Omu
Omu

Reputation: 71188

thread safe map for java

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

Answers (8)

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

Basil Bourque
Basil Bourque

Reputation: 338181

Interfaces

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.

Classes

Modifiable maps

Java provides two classes that implement those interfaces. Third-party libraries may also provide classes implementing those interfaces. The classes bundled with Java are:

Example usage:

ConcurrentMap < Project , Person > map = new ConcurrentHashMap<>() ;

…and:

ConcurrentNavigableMap < Month , Person > map = new ConcurrentSkipListMap <>() ;

Unmodifiable maps

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.

Legacy map

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 of Hashtable. If a thread-safe highly-concurrent implementation is desired, then it is recommended to use ConcurrentHashMap in place of Hashtable.

Table of Map classes

Here 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.

Table of map implementations in Java 11, comparing their features

Upvotes: 2

Paul Wagland
Paul Wagland

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

Paul Tomblin
Paul Tomblin

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

Pascal Thivent
Pascal Thivent

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

rtperson
rtperson

Reputation: 11708

Your map "list" needs to be static if you want to access it in a static block.

Upvotes: 1

nos
nos

Reputation: 229058

Use ConcurrentHashMap

Upvotes: 8

Bozho
Bozho

Reputation: 597016

java.util.concurrent.ConcurrentHashMap

Upvotes: 108

Related Questions