Question

@Singleton
@LocalBean
@Startup
@ConcurrencyManagement(ConcurrencyManagementType.BEAN)
public class DeliverersHolderSingleton {

    private volatile Map<String, Deliverer> deliverers;

    @PostConstruct
    private void init() {
        Map<String, Deliverer> deliverersMod = new HashMap<>();
        for (String delivererName : delivererNames) {
            /*gettig deliverer by name*/
            deliverersMod.put(delivererName, deliverer);
        }
        deliverers = Collections.unmodifiableMap(deliverersMod);
    }

    public Deliverer getDeliverer(String delivererName) {
        return deliverers.get(delivererName);
    }

    @Schedule(minute="*", hour="*")
    public void maintenance() {
        init();
    }
}

Singleton is used for storing data. Data is updated once per minute. Is it possible, that read from the unmodifiableMap will be a problem with the synchronization? Is it possible that it will occurs reordering in init method and link to the collection will published, but collection not filled completely?

Was it helpful?

Solution

The Java Memory Model guarantees that there is a happens-before relationship between a write and a subsequent read to a volatile variable. In other words, if you write to a volatile variable and subsequently read that same variable, you have the guarantee that the write operation will be visible, even if multiple threads are involved:

A write to a volatile field (§8.3.1.4) happens-before every subsequent read of that field.

It goes further and guarantees that any operation that happened before the write operation will also be visible at the reading point (thanks to the program order rule and the fact that the happens-before relationship is transitive).

Your getDeliverers method reads from the volatile variable so it will see the latest write operated on the line deliverers = Collections.unmodifiableMap(deliverersMod); as well as the preceding operations where the map is populated.

So your code is thread safe and your getDeliverers method will return a result based on the latest version of your map.

OTHER TIPS

According to the Reordering Grid found here http://g.oswego.edu/dl/jmm/cookbook.html, the 1st operation being Normal Store cannot be reordered with the second operation being Volatile Store, so in your case, as long as the immutable map is not null, there wouldn't be any reordering problems.

Also, all writes that occur prior to a volatile store will be visible, so you will not see any publishing issues.

Thread safety issues here:

  • multiple reads from the HashMap - is thread safe, because multiple reads are allowed as long as there are no modifications to the collection and writes to the HashMap will not happen, because the map is an unmodifiableMap()

  • read/write on deliverers - is thread safe, because all java reference assignments are atomic

I can see no thread-unsafe operations here.

I would like to note that the name of init() metod is misleading, it suggests that it is called once during initialization; I'd suggest calling it rebuild() or recreate().

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top