[concurrency-interest] ConcurrentHashMap NullPointerException

Endre Stølsvik Online at stolsvik.com
Sat Jan 5 06:52:48 EST 2008


BJ Low wrote:
> Hi,
> 
> I am pretty sure of below. It is very hard for me to post the code cause 
> the code is proprietary, but perhaps let me ask this in another way
> 
> Suppose I have a class below
> 
> class X {
>      int i = 0;
>     
>      void changeVal(int i) {
>         this.i = i;
>      }
> 
>      int readVal() {
>         return this.i;
>      }
> }
> 
> At time t1, Thread-X submits a Runnable to threadpool,
> At time t2, Thread-1 from the threadpool runs the Runnable and call 
> changeVal(1);
> At time t3, Thread-X submits another Runnable to threadpool
> At time t4, Thread-2 from the threadpool runs the Runnable and call 
> readVal();
> 
> The question is, will Thread-2 see the value of i as 0 or 1? 

"Thread-X" - is that supposed to be the same thread at the two times? 
Because I personally use "X" as "some".

But lets assumes that (it doesn't really matter either - this is broken 
no matter!).

There's no reason to argue complex memory situations and happens-before 
or anything like that here - this is plain as day: Thread X works on its 
own, and thus basically submits two jobs right after each other. For the 
sake of the argument: The first runnable, in Thread-1, takes 3 hours to 
complete, finally doing changeVal(1). The second Runnable runs readVal() 
about .001 ms after submit. What is the answer?

And the time labels "t[1-4]" is of no use what so ever when interleaved 
between threads that doesn't do explicit synchronization. Assuming again 
that Thread-X is the same in both instances, there is a "t, t+x" 
situation between the two submits (the first submit /happens-before/ the 
second submit, by way of code order).
   However, one cannot argue anything about Thread-1 (other than that it 
happens AFTER the submit of itself, which is at "t"), and Thread-2 
(other than that is happens AFTER the submit of itself, which is at "t+x").
   The order of _when_ those two runnables are run on their respective 
worker threads, is fully non-deterministic: both the work they do (the 
time it takes), the inner workings of the thread pool (e.g. whether a 
new Thread has to be made for one of the submissions, perhaps the first, 
not the second) - and finally, the operating system: it might decide 
based on some cosmic reasons, that Thread-1 shouldn't run, or is 
pre-empted before the changeVal() while a whole bunch of other threads 
gets time slices, while Thread-2 by the same unfair magic gets scheduled 
right away.

These are really basic multi-threading issues, not having anything to do 
with complex code-reorderings or anything like that.

What you want here, is synchronized code in class X, and some flag that 
denotes whether the job is done. The flag is set to true when 
"changeVal()" is run, and then the /this X/ is .notify()ed (within 
synchronized on /this X/, of course). The readVal() method checks 
(within synchronzied on /this X/, of course) whether the flag is true. 
If it isn't it goes into .wait() on /this X/, looping until flag is true 
(must loop due to "spurious wakeups"). Hey presto.. Also check out 
Callable vs. Future - it does just this.

Endre.


More information about the Concurrency-interest mailing list