ConcurrentHashMap reorder-Anweisung?

Ich bin auf der Suche in ConcurrentHashMap Umsetzung und eine Sache machen, die mich verwirrt.

/* Specialized implementations of map methods */

        V get(Object key, int hash) {
            if (count != 0) { //read-volatile
                HashEntry<K,V> e = getFirst(hash);
                while (e != null) {
                    if (e.hash == hash && key.equals(e.key)) {
                        V v = e.value;
                        if (v != null)
                            return v;
                        return readValueUnderLock(e); //recheck
                    }
                    e = e.next;
                }
            }
            return null;
        }

und

    /**
     * Reads value field of an entry under lock. Called if value
     * field ever appears to be null. This is possible only if a
     * compiler happens to reorder a HashEntry initialization with
     * its table assignment, which is legal under memory model
     * but is not known to ever occur.
     */
    V readValueUnderLock(HashEntry<K,V> e) {
        lock();
        try {
            return e.value;
        } finally {
            unlock();
        }
    }

und HashEntry Konstruktor

/**
     * ConcurrentHashMap list entry. Note that this is never exported
     * out as a user-visible Map.Entry.
     *
     * Because the value field is volatile, not final, it is legal wrt
     * the Java Memory Model for an unsynchronized reader to see null
     * instead of initial value when read via a data race.  Although a
     * reordering leading to this is not likely to ever actually
     * occur, the Segment.readValueUnderLock method is used as a
     * backup in case a null (pre-initialized) value is ever seen in
     * an unsynchronized access method.
     */
    static final class HashEntry<K,V> {
    final K key;
            final int hash;
            volatile V value;
            final HashEntry<K,V> next;

            HashEntry(K key, int hash, HashEntry<K,V> next, V value) {
                this.key = key;
                this.hash = hash;
                this.next = next;
                this.value = value;
            }

setzen implementieren

tab[index] = new HashEntry<K,V>(key, hash, first, value);

Ich verwirrt HashEntry Kommentar, als JSR-133, einmal HashEntry aufgebaut ist, alle final-Felder werden sichtbar für alle anderen threads, Wert Feld ist flüchtig, so dass ich denke, dass es sichtbar für andere threads zu??? . Anderer Punkt, ist der reorder sagte er: HashEntry Objektreferenz zugewiesen werden kann, um die Registerkarte [...], bevor es voll ist gebaut (also Ergebnis ist in anderen threads sehen kann, dieser Eintrag, aber e.der Wert kann null sein) ?

Update:
Ich lese diese Artikel und es ist gut. Aber muss ich darum kümmern muss, einen Fall wie diesen

ConcurrentLinkedQueue queue = new ConcurrentLinkedQueue();

thread1:

Person p=new Person("name","student");        
queue.offer(new Person());

thread2:
Person p = queue.poll();

Ist es eine chance, dass Thread2 verzahnt, erhalten eine unvollendete-Konstrukt Person, Objekt, genau wie HashEntry in

Registerkarte[index] = new HashEntry(Schlüssel, hash, ersten, Wert);
?

  • Mit Wert flüchtige sicherzustellen, können Sie die Sichtbarkeit von allen anderen threads.
  • yep, so dass alle Felder sichtbar sind, die durch alle anderen threads, also, warum wir nur brauchen, um über den Wert von 'value', null sein?
InformationsquelleAutor secmask | 2011-02-15
Schreibe einen Kommentar