Reputation: 16231
Suppose I have a shared object of class:
class Shared {
private int x = 0 ;
private int y = 0 ;
private Semaphore s = new Semaphore() ;
public int readX() {
s.p() ;
int x0 = x ;
s.v() ;
return x0 ; }
public void writeX(int x0) {
s.p() ;
x = x0 ;
s.v() ; }
public int readY() {
s.p() ;
int y0 = y ;
s.v() ;
return y0 ; }
public void writeY(int y0) {
s.p() ;
y = y0 ;
s.v() ; } }
Here Semaphore is a class that uses synchronized methods to provide mutual exclusion.
Now the following actions happen:
Could thread 0 read from its cache and find that x is 0? Why?
EDIT
Here is the Semaphore class
class Semaphore {
private boolean available = true ;
public synchronized void v() {
available = true ; notifyAll() ; }
public synchronized void p() {
while( !available ) try{ wait() ; } catch(InterruptedException e){}
available = false ; }
}
Upvotes: 1
Views: 106
Reputation: 200166
Presenting the actions of your two threads side-by-side:
Thread 1 Thread 2 o.readX(); // 0 o.writeX(1); o.readY(); // 1 o.writeY(1); o.readX(); // must be 1
There is a strict happens-before ordering of any arbitrarily chosen pair of invocations of your Semaphore
methods because they both go through an acquire-release cycle on the same shared Semaphore
instance.
We have:
o.writeX(1)
by Thread 2 happens-before o.writeY(1)
;o.writeY(1)
by Thread 2 happens-before o.readY() -> 1
by Thread 1;o.readY()
by Thread 1 happens-before the second o.readX()
by Thread 1;o.writeX(1)
by Thread 2 happens-before the second o.readX()
by Thread 1;o.readX()
must be 1.Upvotes: 3
Reputation: 15861
According to JMM the following sequence is strictly ordered by happens-before relationship and therefore guarantees visibility of change done in the step 1 to reader at step 4:
Write to variable happens-before releasing the monitor, releasing the monitor happens-before acquiring the same monitor and acquiring the monitor happens-before read from variable.
So if p
and v
are synchronized then thread 0 will see the change to x.
Upvotes: 3