-
Bug
-
Resolution: Won't Fix
-
P3
-
None
-
1.0
-
sparc
-
solaris_2.3
In the typical thread synchronization example : producer-consumer problem.
producer and consumer share a limited buffer.
One producer and two consumers access the buffer. Although consumer cth2
has the same priority as the consumer cth1, consumer th2 never has chance
to run (starvation) until the consumer cth1 finishes. This problem is
caused by the simple prority and FIFO scheduling. It may need one aging
mechanism to make scheduling fair.
Also the documentary on notify() and wait() needs to explain the thread
synchronization model such as the highest priority waiting thread is
chosen to run next when entering monitor.
It seems to me that priority inheritance policy is taken when a thread
attempts to enter the monitor so that the real time thread gets a
bounded delay(execution time of the critical section code). This needs
to be detailed in the documentary.
----------code---------
class pcbuffer {
private threadsafe int buf_size;
private threadsafe int stock;
private long prod_time ;
private long cons_time;
private boolean debugflag;
private boolean waitflag;
private boolean failed;
private char execflow[];
private int seq; // sequence number of access to critical section
pcbuffer( )
{
buf_size = 20;
stock = 0;
prod_time = 0;
cons_time = 0;
debugflag = true;
waitflag = true;
failed = false;
execflow = new char[100];
seq = 0;
}
public synchronized void put()
{
if ( stock < buf_size ) {
if ( debugflag )
System.out.println(Thread.currentThread().getName() + " attempts to put one ball\\
from buffer successfully at " + System.currentTimeMillis());
execflow[seq++] = 'p';
stock++;
notifyAll();
waitflag = false;
//notify();
}
else {
if ( debugflag )
System.out.println(Thread.currentThread().getName() + " attempts to put one ball\\
from buffer failed at " + System.currentTimeMillis() + " wait ....");
execflow[seq++] = 'p';
while (stock > buf_size ) wait();
stock++;
//notifyAll();
if ( debugflag )
System.out.println(Thread.currentThread().getName() + " is waken up m waiting\\
at " + System.currentTimeMillis());
execflow[seq++] = 'p';
}
}
public synchronized void pop()
{
if ( stock > 0 ) {
execflow[seq++] = 'c';
stock--;
if ( debugflag )
System.out.println(Thread.currentThread().getName() + " attempts to take one ball\\
from buffer successfully at " + System.currentTimeMillis());
//notify();
notifyAll();
}
else
{
long t1, t2;
t1 = System.currentTimeMillis();
execflow[seq++] = 'c';
if ( debugflag )
System.out.println(Thread.currentThread().getName() + " attempts to take one ball\\
from buffer failed at " + t1);
waitflag = true;
// note while(..) is necessary to make sure stock > 0 after being waken up
while ( stock == 0 )
{
System.out.println(Thread.currentThread().getName() + " waiting...");
wait();
t2 = System.currentTimeMillis();
if ( debugflag )
System.out.println(Thread.currentThread().getName() + " is waken up from waiting\\
at " + t2);
}
stock--;
//notifyAll();
execflow[seq++] = 'c';
// make sure producer changes the flag.
if ( waitflag )
{
failed = true;
}
else
{
failed = false;
}
}
}
public int getstock() { return stock; }
public boolean isok()
{
boolean cflow = true;
// here we don't check the timing of execution flow.
return ( stock == 5 && failed == false && cflow);
}
}
/**
* Thread producer puts one ball into the buffer.
* overriding the run().
*/
class producer extends Thread {
private pcbuffer buf;
producer(pcbuffer buf)
{
this.buf = buf;
}
public void run() {
int i = 0;
while( i < 10) {
buf.put();
System.out.println(getName() + ": The number of balls in buffer = " + buf.getstock());
i++;
//Thread.sleep( 20);
}
}
}
class consumer extends Thread {
private pcbuffer buf