-
Bug
-
Resolution: Fixed
-
P3
-
6
-
b13
-
generic
-
generic
-
Not verified
Issue | Fix Version | Assignee | Priority | Status | Resolution | Resolved In Build |
---|---|---|---|---|---|---|
JDK-8030233 | 6u75 | Robert Mckenna | P3 | Closed | Fixed | b01 |
Doug Lea writes:
---------
In an exchange with Hans Boehm, he pointed out that contrary to
reasonable expectations users probably have, a WeakHashMap that
is not being modified is NOT concurrently readable by multiple threads.
As he said...
>> On the other hand, with two threads concurrently reading the WeakHashMap
>> (e.g. by calling size()), two threads end up concurrently removing
>> enqueued elements from the WeakHashMap at the same time, which I very
>> strongly suspect can result in a mangled data structure.
>>
The current wording of the javadoc spec might make you believe otherwise.
Rather than changing the spec, we should fix the code. It's easy --
just use a lock around the deletion code in expungeStaleEntries.
(And conveniently, the "queue" makes a perfectly good lock-object.
(The diffs below are mostly just indents.)
As I said to Hans...
>> It's a little weird
>> making this class only a little thread-safe, but you are right that as it
>> stands, someone will someday be unhappily surprised.
Could you file a bug report on this.
% diff 1.6.0/j2se/martin/j2se/src/share/classes/java/util/WeakHashMap.java
jsr166/src/main/java/util/
275,290c275,294
< int h = e.hash;
< int i = indexFor(h, table.length);
<
< Entry<K,V> prev = table[i];
< Entry<K,V> p = prev;
< while (p != null) {
< Entry<K,V> next = p.next;
< if (p == e) {
< if (prev == e)
< table[i] = next;
< else
< prev.next = next;
< e.next = null; // Help GC
< e.value = null; // " "
< size--;
< break;
---
> synchronized(queue) {
> int h = e.hash;
> int i = indexFor(h, table.length);
>
> Entry<K,V> prev = table[i];
> Entry<K,V> p = prev;
> while (p != null) {
> Entry<K,V> next = p.next;
> if (p == e) {
> if (prev == e)
> table[i] = next;
> else
> prev.next = next;
> e.next = null; // Help GC
> e.value = null; // " "
> size--;
> break;
> }
> prev = p;
> p = next;
292,293d295
< prev = p;
< p = next;
---------
---------
In an exchange with Hans Boehm, he pointed out that contrary to
reasonable expectations users probably have, a WeakHashMap that
is not being modified is NOT concurrently readable by multiple threads.
As he said...
>> On the other hand, with two threads concurrently reading the WeakHashMap
>> (e.g. by calling size()), two threads end up concurrently removing
>> enqueued elements from the WeakHashMap at the same time, which I very
>> strongly suspect can result in a mangled data structure.
>>
The current wording of the javadoc spec might make you believe otherwise.
Rather than changing the spec, we should fix the code. It's easy --
just use a lock around the deletion code in expungeStaleEntries.
(And conveniently, the "queue" makes a perfectly good lock-object.
(The diffs below are mostly just indents.)
As I said to Hans...
>> It's a little weird
>> making this class only a little thread-safe, but you are right that as it
>> stands, someone will someday be unhappily surprised.
Could you file a bug report on this.
% diff 1.6.0/j2se/martin/j2se/src/share/classes/java/util/WeakHashMap.java
jsr166/src/main/java/util/
275,290c275,294
< int h = e.hash;
< int i = indexFor(h, table.length);
<
< Entry<K,V> prev = table[i];
< Entry<K,V> p = prev;
< while (p != null) {
< Entry<K,V> next = p.next;
< if (p == e) {
< if (prev == e)
< table[i] = next;
< else
< prev.next = next;
< e.next = null; // Help GC
< e.value = null; // " "
< size--;
< break;
---
> synchronized(queue) {
> int h = e.hash;
> int i = indexFor(h, table.length);
>
> Entry<K,V> prev = table[i];
> Entry<K,V> p = prev;
> while (p != null) {
> Entry<K,V> next = p.next;
> if (p == e) {
> if (prev == e)
> table[i] = next;
> else
> prev.next = next;
> e.next = null; // Help GC
> e.value = null; // " "
> size--;
> break;
> }
> prev = p;
> p = next;
292,293d295
< prev = p;
< p = next;
---------
- backported by
-
JDK-8030233 (coll) WeakHashMap thread safety
-
- Closed
-