0

I have a map (let's call it original map), which is initially null. During service deployment and every hour after that, I need to refresh this map or basically reassing it.

Here is how I do it. In the refresh, I create a new map, and return an unmodifiableMap view of that new map, to my original map, now while this reassignment happens, that is the reference for original map gets changed, will it impact any other thread currently accessing the original map? Thing to note is during the service deployment, the original map is assigned a value in the similar fashion, basically the same refresh strategy is used.

        private static Map<String, PricingPriceList> plInfoByName;
        TransactionData.plInfoByName = plInfo.get(0);

Here plInfoByName is my original map, and plInfo contains a list of unmodifable maps. Here is how plInfo list is populated

    Map<String, PricingPriceList> plInfoByName = new HashMap<String, PricingPriceList>();
    Map<String, PricingPriceList> plInfoById = new HashMap<String, PricingPriceList>();

    try {
        stmt = dbConn.createStatement();
        stmt.setFetchSize(10000);

        rs = stmt.executeQuery(query);
        PricingPriceList plDetails = null;
        while (rs.next()) {
            plDetails = new PricingPriceList();

            //populate plDetails attributes

            plInfoByName.put(rs.getString(0), plDetails);
            plInfoById.put(rs.getString(1), plDetails);
        }

    } catch (Exception e) {
        LOGGER.ERROR("Error executing refreshPlInfo. Affected in-memory objects: plInfoByName, plInfoById.", e);
    } finally {
        try {
            if (stmt != null && !stmt.isClosed()) {
                stmt.close();
            }
            if (rs != null && !rs.isClosed()) {
                rs.close();
            }
        } catch (SQLException e) {
            LOGGER.ERROR("refreshPlInfo failed to close SQL statement or resultset.", e);
        }

    }

    // Return unmodifiable version
    List<Map<String, PricingPriceList>> plInfo = new ArrayList<Map<String, PricingPriceList>>();
    plInfo.add(Collections.unmodifiableMap(plInfoByName));
    plInfo.add(Collections.unmodifiableMap(plInfoById));
    return plInfo;

So when I do this, will it impact any thread reading TransactionData.plInfoByName? Or is it thread safe cause it's an unModifiableMap that is stored in it.

    TransactionData.plInfoByName = plInfo.get(0);
Arnav Sengupta
  • 423
  • 1
  • 7
  • 19

1 Answers1

2

An unmodifiableMap isn't threadsafe by itself, it just prevents users from changing it. Another thread that has access to the underlying map could still change it while the current thread is reading.

However, if you just change the reference to the map, it should not affect any thread that is currently accessing the "old" map. Assuming (I'd have to check that) that getting the reference to an object is a more or less atomic operation (see here: What operations in Java are considered atomic?), any thread that got the reference to the "old" map should keep it until it retrieves the reference again.

Example:

Assume the following operations:

  • variable "map" contains the reference to map A
  • T1 retrieves map A through "map" and stores that reference in some local variable, let's call call it "t1Map"
  • T2 changes "map" to refernence map B now
  • T1 accesses the map through "t1Map" which still references A
  • T1 retrieves map A through "map" again and will now get the reference to B
Community
  • 1
  • 1
Thomas
  • 87,414
  • 12
  • 119
  • 157
  • So we need to just confirm whether this assignment operation in java is atomic or not? Actually that is what my primary concern is, will the reassigning impact any current thread. – Arnav Sengupta Mar 11 '16 at 16:27
  • @ArnavSengupta have a look at the thread I linked. It says that assignments are atomic - I'd have to look up the corresponding section in the JLS. – Thomas Mar 11 '16 at 16:29
  • Just to add, the threads do not store it in a local variable, they all read from this common map, TransactionData.plInfoByName. – Arnav Sengupta Mar 11 '16 at 16:29
  • Thanks, this helps, just checked it reference assignments seem atomic, so it should be fine – Arnav Sengupta Mar 11 '16 at 16:31