< prev index next >
src/java.base/share/classes/java/util/Properties.java
Print this page
*** 47,56 ****
--- 47,58 ----
import java.util.function.Function;
import jdk.internal.misc.SharedSecrets;
import jdk.internal.util.xml.PropertiesDefaultHandler;
+ import jdk.internal.misc.Unsafe;
+
/**
* The {@code Properties} class represents a persistent set of
* properties. The {@code Properties} can be saved to a stream
* or loaded from a stream. Each key and its corresponding value in
* the property list is a string.
*** 154,165 ****
* Properties does not store values in its inherited Hashtable, but instead
* in an internal ConcurrentHashMap. Synchronization is omitted from
* simple read operations. Writes and bulk operations remain synchronized,
* as in Hashtable.
*/
! private transient ConcurrentHashMap<Object, Object> map;
/**
* Creates an empty property list with no default values.
*
* @implNote The initial capacity of a {@code Properties} object created
* with this constructor is unspecified.
--- 156,170 ----
* Properties does not store values in its inherited Hashtable, but instead
* in an internal ConcurrentHashMap. Synchronization is omitted from
* simple read operations. Writes and bulk operations remain synchronized,
* as in Hashtable.
*/
! private transient final ConcurrentHashMap<Object, Object> map;
+ private static final Unsafe UNSAFE = Unsafe.getUnsafe();
+ private static final long MAP_OFFSET
+ = UNSAFE.objectFieldOffset(Properties.class, "map");
/**
* Creates an empty property list with no default values.
*
* @implNote The initial capacity of a {@code Properties} object created
* with this constructor is unspecified.
*** 1471,1481 ****
protected void rehash() { /* no-op */ }
@Override
public synchronized Object clone() {
Properties clone = (Properties) cloneHashtable();
! clone.map = new ConcurrentHashMap<>(map);
return clone;
}
//
// Hashtable serialization overrides
--- 1476,1486 ----
protected void rehash() { /* no-op */ }
@Override
public synchronized Object clone() {
Properties clone = (Properties) cloneHashtable();
! UNSAFE.putObjectVolatile(clone, MAP_OFFSET, new ConcurrentHashMap<>(map));
return clone;
}
//
// Hashtable serialization overrides
*** 1535,1549 ****
// what is actually created.
SharedSecrets.getJavaObjectInputStreamAccess()
.checkArray(s, Map.Entry[].class, HashMap.tableSizeFor((int)(elements / 0.75)));
// create CHM of appropriate capacity
! map = new ConcurrentHashMap<>(elements);
// Read all the key/value objects
for (; elements > 0; elements--) {
Object key = s.readObject();
Object value = s.readObject();
! map.put(key, value);
}
}
}
--- 1540,1555 ----
// what is actually created.
SharedSecrets.getJavaObjectInputStreamAccess()
.checkArray(s, Map.Entry[].class, HashMap.tableSizeFor((int)(elements / 0.75)));
// create CHM of appropriate capacity
! ConcurrentHashMap<Object,Object> tmpMap = new ConcurrentHashMap<>(elements);
// Read all the key/value objects
for (; elements > 0; elements--) {
Object key = s.readObject();
Object value = s.readObject();
! tmpMap.put(key, value);
}
+ UNSAFE.putObjectVolatile(this, MAP_OFFSET, tmpMap);
}
}
< prev index next >