[concurrency-interest] Synchronization blocks, locks and reorderings

Larry Riedel larryr at saturn.sdsu.edu
Wed Jan 23 19:31:22 EST 2008


> >   public void writer() {
> >     x = 1;
> >     synchronized (l) {
> >       y = 2;
> >     }
> >   }
> >   public void reader() {
> >     synchronized (l) {
> >       int r1 = y;
> >       int r2 = x;
> >     }
> >   }
> 
> If I understand it correctly, the text explains this scenario:
> 
> time writer()        reader()
> ---- --------        --------
> t1   write to x
> t2   lock l
> t3   write to y
> t4   unlock l
> t5                   lock l
> t6                   read y
> t7                   read x
> t8                   unlock l
> 
> There is nothing special about it except for that the shared
> variable x is only handled correctly because it appears just
> before a critical section and the change has some latch effect.

I think of that latch effect as a major fundamental feature
associated with "synchronized", which makes it do more than just
synchronize thread sequencing, it also synchronizes thread state.


> time writer()        reader()
> ---- --------        --------
> t1                   lock l
> t2                   read y
> t3   write to x
> t4                   read x
> t5                   unlock l
> t6   lock l
> t7   write to y
> t8   unlock l
> 
> Now what value of x will the reader read? According to
> the happens-before stuff, value 0 will be read from x
> despite that x has actually value 1 already.

I think by putting the write to x before the synchronized
block, I am saying it is ok for another thread to see the
change to x before the change to y, but not vice versa.


> with the fancy "happens-before" interpretation of Java,
> even the following non-sense piece of code is "correct":
>   [...]
>   public void writer() {
>     x = 1;
>     y = 2;
>     synchronized (l) {
>     }
>   }

Maybe if it was 
    public void writer() {
        x = 1;
        y = 2;
        synchronized (l);
    }
it would seem less like nonsense, because it is more
clearly saying I want other threads synchronizing state
with me through l to see the changes I made to x and y
no later than the next time they do synchronized(l),


> time writer()        reader()
> ---- --------        --------
> t1   write to x
> t2                   lock l
> t3   write to y
> t4                   read y
> t5                   read x
> t6                   unlock l
> t7   lock l
> t8   unlock l
> 
> After this scenario, on the other hand, the result will be, I
> guess, r1==0, r2==0 which is something extra ordinary. What
> "happened-before" defines in Java is not what happened before.

"Happened before" confuses me too; I think of it more
as "was published before" as far as seeing state changes.


> The referred article claims: `Many developers
> mistakenly assume that synchronization is simply a
> shorthand for "critical section" or "mutex".'---Well,
> I am one of them. At least the keyword `synchronized'
> should mark a block which is a critical section [...]

Maybe it would be better to say they mistakenly presume
that "synchronized" is /only/ used as critical sections,
when it is also used as a mechanism for threads to
synchronize their state.  I am not sure if having an
additional semantically distinct construct would have
made reading or writing programs any easier in practice.


Larry



More information about the Concurrency-interest mailing list