S
S
shurik25332013-07-08 17:29:46
Java
shurik2533, 2013-07-08 17:29:46

Reordering when posting a link to an UnmodifiableMap?

We have EJB Singleton. In it, after the object is created (but before publication), the rebuild () method is launched, marked with the @PostConstruct annotation. We have a scheduler that runs the same method once a minute. The method initializes the collection, wraps it in an UnmodifiableMap and places it via volatile into the deliverers variable.

We also have a public getDeliverer method that reads data from UnmodifiableMap deliverers in another thread.

@Singleton<br>
@LocalBean<br>
@Startup<br>
@ConcurrencyManagement(ConcurrencyManagementType.BEAN)<br>
public class DeliverersHolderSingleton {<br>
<br>
    private volatile Map<String, Deliverer> deliverers;<br>
<br>
    @PostConstruct<br>
    private void rebuild() {<br>
        Map<String, Deliverer> deliverersMod = new HashMap<>();<br>
        for (String delivererName : delivererNames) {<br>
            /*gettig deliverer by name*/<br>
            deliverersMod.put(delivererName, deliverer);<br>
        }<br>
        deliverers = Collections.unmodifiableMap(deliverersMod);<br>
    }<br>
<br>
    public Deliverer getDeliverer(String delivererName) {<br>
        return deliverers.get(delivererName);<br>
    }<br>
<br>
    @Schedule(minute="*", hour="*")<br>
    public void maintenance() {<br>
        rebuild();<br>
    }<br>
}<br>


Could it be that, as a result of reordering, the link is published before the collection is initialized?
For example, thread A, in which the init() method is called, will first assign a reference to the UnmodifiableMap to the deliverers variable (publishing the reference itself will be safe, because it is volatile), and after that it will initialize our UnmodifiableMap.

This, it seems to me, does not contradict the Java Memory Model. Specificationsays that the compiler is allowed to reorder the instructions in either thread, when this does not affect the execution of that thread in isolation. In this case, there is no influence and the permutation seems possible, as it seemed to me.

So, thread B calls the getDeliverer method at the moment when the reference to the UnmodifiableMap has already been assigned, but the collection itself seems to be not completed, because Thread A has been reordered. So, dear experts, can this be the case? Something tells me it can't, but I can't prove it. I ask for your help.

Answer the question

In order to leave comments, you need to log in

2 answer(s)
A
Artyushov, 2013-07-08
@Artyushov

Since volatile write and volatile read are in a happens-before relationship, the thread reading the value will see all the actions that the thread that called rebuild() did before volatile write. That is, inside one thread, all operations are in the happens-before relationship, and since this relationship is transitive, other threads will already see the correct value of the variable.

G
gvsmirnov, 2013-07-08
@gvsmirnov

No, he can not. If another thread sees the deliverersdesired link, then everything that you put there in another thread will also be visible. Read, for example, here: habrahabr.ru/post/143390/

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question