Readers and Writers problem
Hi,
I just thought of a case to illustrate the use of the "synchronized" keyword. As per my understanding, if a method is scoped as synchronized, then only one thread will be executing on it at any instant of time.
In this example, I have a "Bound" object which maintains two integers - lower and upper. The constraint is that at any point of time, lower <= upper. Let me assume that the domain is {0,1,2,3,4,5}.
class Bound
{
privateint lower, upper;
public Bound(int lower,int upper)
{
setLower(lower);
setUpper(upper);
}
publicint getLower()
{
return lower;
}
publicint getUpper()
{
return upper;
}
publicsynchronizedvoid setUpper(int value)
{
if (value < lower)
{
thrownew IllegalArgumentException();
}
upper = value;
}
publicsynchronizedvoid setLower(int value)
{
if (value > upper)
{
thrownew IllegalArgumentException();
}
lower = value;
}
}
Now I have two thread classes - a writer and a reader. The writer sets random values onto the "Bound" object, and the reader keeps reading those values:
class Writerextends Thread
{
private Bound b;
private Random r;
public Writer(Bound b)
{
this.b = b;
r =new Random();
setDaemon(true);
}
publicvoid run()
{
while(true)
{
try
{
b.setLower(Math.abs(r.nextInt()%6));
b.setUpper(Math.abs(r.nextInt()%6));
}
catch(IllegalArgumentException e)
{
//Ignore the exception
}
}
}
}
class Readerextends Thread
{
private Bound b;
public Reader(Bound b)
{
this.b = b;
}
publicvoid run()
{
long currTime = System.currentTimeMillis();
while(true)
{
int lower = b.getLower();
int upper = b.getUpper();
System.out.println(" " + lower +" " + upper);
if (upper < lower)
{
long endTime = System.currentTimeMillis();
System.out.println("Inconsistency occurred in " + (endTime - currTime) +" ms");
break;
}
}
}
}
Now I create a Bound object, and share it with three writers and a reader:
publicclass ThreadTest
{
publicstaticvoid main(String[] args)
{
Bound b =new Bound(0,5);
Thread t1 =new Writer(b);
Thread t2 =new Writer(b);
Thread t3 =new Writer(b);
Thread t4 =new Reader(b);
t1.start();
t2.start();
t3.start();
t4.start();
try
{
t4.join();
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
I never expected the inconsistency to occur because the setXXX( ) methods were synchronized. But however, in all the trial runs, I have ended up in an inconsistent Bound object, within 30 seconds or so.
I am sure that there must be something wrong in my code :-). Could anyone of you point out the mistake?
Thanks and Regards,
Kumar.

