这是《Java How To Program》中的例子:生产者与消费者的问题
public class HoldIntegerSynchronized {
private int sharedInt = -1;
private boolean writeable = true; // condition variable public synchronized void setSharedInt( int val )
{
while ( !writeable ) { // not the producer's turn
try {
wait();
}
catch ( InterruptedException e ) {
e.printStackTrace();
}
} System.err.println( Thread.currentThread().getName() +
" setting sharedInt to " + val );
sharedInt = val; writeable = false;
notify(); // tell a waiting thread to become ready
} public synchronized int getSharedInt()
{
while ( writeable ) { // not the consumer's turn
try {
wait();
}
catch ( InterruptedException e ) {
e.printStackTrace();
}
} writeable = true;
notify(); // tell a waiting thread to become ready System.err.println( Thread.currentThread().getName() +
" retrieving sharedInt value " + sharedInt );
return sharedInt;
}
}
public class ProduceInteger extends Thread {
private HoldIntegerSynchronized pHold; public ProduceInteger( HoldIntegerSynchronized h )
{
super( "ProduceInteger" );
pHold = h;
} public void run()
{
for ( int count = 1; count <= 10; count++ ) {
// sleep for a random interval
try {
Thread.sleep( (int) ( Math.random() * 3000 ) );
}
catch( InterruptedException e ) {
System.err.println( e.toString() );
} pHold.setSharedInt( count );
} System.err.println( getName() +
" finished producing values" +
"\nTerminating " + getName() );
}
}public class ConsumeInteger extends Thread {
private HoldIntegerSynchronized cHold; public ConsumeInteger( HoldIntegerSynchronized h )
{
super( "ConsumeInteger" );
cHold = h;
} public void run()
{
int val, sum = 0; do {
// sleep for a random interval
try {
Thread.sleep( (int) ( Math.random() * 3000 ) );
}
catch( InterruptedException e ) {
System.err.println( e.toString() );
} val = cHold.getSharedInt();
sum += val;
} while ( val != 10 ); System.err.println(
getName() + " retrieved values totaling: " + sum +
"\nTerminating " + getName() );
}
}
请问在监控器HoldIntegerSynchronized 中,getSharedInt()中还没有返回sharedInt的值,监控器的条件变量writeable就被赋予“true”还调用了方法notigy()。那么不是就启动生产者的线程了,就可以调用setSharedInt()了,从而就可以更改shareInt的值了吗?那不是若getSharedInt()中还没有来得及返回sharedInt的值就又被新的只覆盖了吗??
public class HoldIntegerSynchronized {
private int sharedInt = -1;
private boolean writeable = true; // condition variable public synchronized void setSharedInt( int val )
{
while ( !writeable ) { // not the producer's turn
try {
wait();
}
catch ( InterruptedException e ) {
e.printStackTrace();
}
} System.err.println( Thread.currentThread().getName() +
" setting sharedInt to " + val );
sharedInt = val; writeable = false;
notify(); // tell a waiting thread to become ready
} public synchronized int getSharedInt()
{
while ( writeable ) { // not the consumer's turn
try {
wait();
}
catch ( InterruptedException e ) {
e.printStackTrace();
}
} writeable = true;
notify(); // tell a waiting thread to become ready System.err.println( Thread.currentThread().getName() +
" retrieving sharedInt value " + sharedInt );
return sharedInt;
}
}
public class ProduceInteger extends Thread {
private HoldIntegerSynchronized pHold; public ProduceInteger( HoldIntegerSynchronized h )
{
super( "ProduceInteger" );
pHold = h;
} public void run()
{
for ( int count = 1; count <= 10; count++ ) {
// sleep for a random interval
try {
Thread.sleep( (int) ( Math.random() * 3000 ) );
}
catch( InterruptedException e ) {
System.err.println( e.toString() );
} pHold.setSharedInt( count );
} System.err.println( getName() +
" finished producing values" +
"\nTerminating " + getName() );
}
}public class ConsumeInteger extends Thread {
private HoldIntegerSynchronized cHold; public ConsumeInteger( HoldIntegerSynchronized h )
{
super( "ConsumeInteger" );
cHold = h;
} public void run()
{
int val, sum = 0; do {
// sleep for a random interval
try {
Thread.sleep( (int) ( Math.random() * 3000 ) );
}
catch( InterruptedException e ) {
System.err.println( e.toString() );
} val = cHold.getSharedInt();
sum += val;
} while ( val != 10 ); System.err.println(
getName() + " retrieved values totaling: " + sum +
"\nTerminating " + getName() );
}
}
请问在监控器HoldIntegerSynchronized 中,getSharedInt()中还没有返回sharedInt的值,监控器的条件变量writeable就被赋予“true”还调用了方法notigy()。那么不是就启动生产者的线程了,就可以调用setSharedInt()了,从而就可以更改shareInt的值了吗?那不是若getSharedInt()中还没有来得及返回sharedInt的值就又被新的只覆盖了吗??
所以读者读的时候总是最新写入的值,
getSharedInt()中返回sharedInt的值应该是最新的,监控器的条件变量writeable就被赋予“true”以后启动生产者的线程,它可以调用setSharedInt()了,从而就可以更改shareInt的值,所以getSharedInt()中还没有来得及返回的sharedInt的值是最新的当然也可以改成读优先,比如说,只要有读者在读或在等待,写者必须挂起,直到没有读者时,再唤醒写进程。
http://www.netyi.net/in.asp?id=wxs_1128
你可能心里面明白但是还是没有说得很清楚.我来说说我的想法吧(今天才想通的)。
方法notify();只是将另外一个线程唤醒使之进入就绪态并没有转入执行态.所以要等到方法 getSharedInt()中的return后,才会切换到写者线程的执行态。所以就不可能出现楼主所说的覆盖的问题。 看来丁丁同学还是审题不清呀。hehe!
那样话楼主的问题还是得不到解决哦,我也被捆饶了,不知道能不能该成把notify放在最后面,去掉return();
。在原来的《组成原理》课上学过,好像是如果要中断的话应该在一条指令执行完后,所以若在notify()唤醒写者后岂不是刚好写着就抢占了CPU吗(写着的优先级高的情况下)。
是不是小弟概念不清?哪位大虾帮小弟解决一下。 在此谢谢 leihailin(exit(0);) 的关注,不过retrun是不能去掉的,要不拿来的读者(消费者)呀? ^_^
同一个类的同步方法都是互斥执行的,那一切都解决了. ^_^看来你得的大分了。
呵呵。