Closed GoogleCodeExporter closed 9 years ago
The code compiles with both Scala 2.7.7 and 2.8.0. I ran this on an 8-core
system and on a year old MacBook Pro and was able to get the same results.
Original comment by blair-ol...@orcaware.com
on 30 Oct 2010 at 1:16
Can you please provide the output that you are seeing when you run this program?
Original comment by fry@google.com
on 2 Nov 2010 at 6:40
Here's a sample run. Thread-0,5,main enters the computing function, then
Thread-5,5,main enters it and leaves it, then Thread-0,5,main leaves it.
There's another time when Thread-8,5,main and Thread-9,5,main are in the
function at the same time.
Thread[Thread-0,5,main] waiting
Thread[Thread-4,5,main] waiting
Thread[Thread-6,5,main] waiting
Thread[Thread-7,5,main] waiting
Thread[Thread-8,5,main] waiting
Thread[Thread-1,5,main] waiting
Thread[Thread-2,5,main] waiting
Thread[Thread-3,5,main] waiting
Thread[Thread-5,5,main] waiting
Thread[Thread-9,5,main] waiting
Thread[Thread-0,5,main] processing
Thread[Thread-4,5,main] processing
Thread[Thread-6,5,main] processing
Thread[Thread-7,5,main] processing
Thread[Thread-8,5,main] processing
Thread[Thread-1,5,main] processing
Thread[Thread-2,5,main] processing
Thread[Thread-3,5,main] processing
Thread[Thread-5,5,main] processing
Thread[Thread-9,5,main] processing
Thread[Thread-6,5,main] getting
Thread[Thread-7,5,main] getting
Thread[Thread-9,5,main] getting
Thread[Thread-4,5,main] getting
Thread[Thread-6,5,main] sleeping in function #1
Thread[Thread-6,5,main] sleeping in function #2
Thread[Thread-5,5,main] getting
Thread[Thread-5,5,main] 1288727312587515000 remove
Thread[Thread-4,5,main] 1288727312587515000 remove
Thread[Thread-5,5,main] getting
Thread[Thread-4,5,main] getting
Thread[Thread-3,5,main] getting
Thread[Thread-2,5,main] getting
Thread[Thread-6,5,main] 1288727312587515000 remove
Thread[Thread-0,5,main] getting
Thread[Thread-0,5,main] sleeping in function #1
Thread[Thread-8,5,main] getting
Thread[Thread-1,5,main] getting
Thread[Thread-7,5,main] 1288727312587515000 remove
Thread[Thread-5,5,main] sleeping in function #1
Thread[Thread-9,5,main] 1288727312587515000 remove
Thread[Thread-5,5,main] sleeping in function #2
Thread[Thread-7,5,main] getting
Thread[Thread-2,5,main] 1288727312589093000 remove
Thread[Thread-3,5,main] 1288727312589093000 remove
Thread[Thread-4,5,main] 1288727312589093000 remove
Thread[Thread-0,5,main] sleeping in function #2
Thread[Thread-0,5,main] 1288727312588824000 remove
Thread[Thread-1,5,main] 1288727312588824000 remove
Thread[Thread-8,5,main] 1288727312588824000 remove
Thread[Thread-6,5,main] getting
Thread[Thread-6,5,main] sleeping in function #1
Thread[Thread-6,5,main] sleeping in function #2
Thread[Thread-6,5,main] 1288727312589850000 remove
Thread[Thread-8,5,main] getting
Thread[Thread-1,5,main] getting
Thread[Thread-0,5,main] getting
Thread[Thread-3,5,main] getting
Thread[Thread-2,5,main] getting
Thread[Thread-7,5,main] sleeping in function #1
Thread[Thread-5,5,main] 1288727312589093000 remove
Thread[Thread-9,5,main] getting
Thread[Thread-7,5,main] sleeping in function #2
Thread[Thread-8,5,main] sleeping in function #1
Thread[Thread-7,5,main] 1288727312590386000 remove
Thread[Thread-9,5,main] sleeping in function #1
Thread[Thread-8,5,main] sleeping in function #2
Thread[Thread-9,5,main] sleeping in function #2
Thread[Thread-9,5,main] 1288727312590740000 remove
Thread[Thread-8,5,main] 1288727312590627000 remove
Thread[Thread-1,5,main] 1288727312590627000 remove
Thread[Thread-3,5,main] 1288727312590627000 remove
Thread[Thread-0,5,main] 1288727312590627000 remove
Thread[Thread-2,5,main] 1288727312590627000 remove
Original comment by blair-ol...@orcaware.com
on 2 Nov 2010 at 7:50
I think it would be a lot easier to reason about your test if you moved the
await to be inside the get. What you really are trying to test is that new
computations aren't started during a pending computation, which you'll find to
be the case once properly tested.
Original comment by fry@google.com
on 5 Nov 2010 at 2:00
Not a scala person but I agree that there is an issue here.
A java test app to do the same looks like:
@Test
public void testAddRemove() throws Exception {
final ConcurrentMap<Integer, Integer> map;
map = new MapMaker()
.makeComputingMap(new Function<Integer, Integer>() {
@Override
public Integer apply(Integer from) {
System.out.println(Thread.currentThread() + ": Loading Key "+from);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread() + ": Completed Loading Key "+from);
return 1;
}
});
new Thread(){
public void run() {
map.get(1);
}}.start();
Thread.sleep(50);
map.remove(1);
new Thread(){
public void run() {
map.get(1);
}}.start();
Thread.sleep(2000);
}
Returns:
Thread[Thread-0,5,main]: Loading Key 1
Thread[Thread-1,5,main]: Loading Key 1
Thread[Thread-0,5,main]: Completed Loading Key 1
Thread[Thread-1,5,main]: Completed Loading Key 1
This shows 2 threads are loading the same key concurrently. This is because the
remove() method does not block in the same way as the get() method for
concurrentMaps. Perhaps all mutating operations on computing maps should block?
Original comment by plh...@googlemail.com
on 22 Dec 2010 at 9:46
This behavior is actually correct.
What this comes down to is a philosophical argument about when an entry being
computed actually enters the map. As currently defined, at the time that the
very first get occurs, a new entry is created, which will be observable by both
size and remove. However the value which that entry maps to is not fully
specified until computation completes.
If you call remove before computation completes then the existing entry is
removed, and while all previously concurrent requests for that entry will
continue to wait for the value, any future request will (correctly) result in
the creation of a _new_ entry.
I think you will find that both of your test cases would be easier to reason
about if you used the two parameter remove(key, value) to avoid a thread
removing an entry it never observed.
Original comment by yrfselrahc@gmail.com
on 14 Jan 2011 at 5:19
This issue has been migrated to GitHub.
It can be found at https://github.com/google/guava/issues/<id>
Original comment by cgdecker@google.com
on 1 Nov 2014 at 4:15
Original comment by cgdecker@google.com
on 3 Nov 2014 at 9:09
Original issue reported on code.google.com by
blair-ol...@orcaware.com
on 30 Oct 2010 at 1:00