В приведенном ниже коде, когда я выполняю класс producercon
, иногда выполнение зависает, выглядит как тупик.Но если я синхронизирую get_flag ()
, то таких проблем нет.
Я не могу понять, как может быть проблема.flag
может иметь значение true или false, поэтому в оператор if
попадет только один из producer
или consumer
.После того, как один из них войдет в if
, он войдет в монитор с объектом r
(оба инициализируются с одинаковой ссылкой на объект).Единственная проблема, которая может произойти, это то, что объект r
изменяется при вызове функции increment_decrement ()
, и get_flag ()
читает флаг одновременно, но даже тогда он не введет if
в этой итерации,но он войдет в блок if
на следующей итерации, и даже если первый поток не покинул монитор, он будет ждать его там (до блока synchronized
).
Как ипочему программа останавливается / зависает, если get_flag ()
не сделан synchronized
?
import java.io.*;
class resource
{
private boolean res, flag;
resource ()
{
flag=false;
}
boolean get_flag ()
{
return flag;
}
void increment_decrement (String s,boolean t)
{
res=t;
flag=t;
try
{
System.out.print("\n"+s+":"+res);
Thread.sleep(200);
}
catch(InterruptedException e)
{
}
}
}
class producer implements Runnable
{
resource r1;
Thread t1;
producer(resource r)
{
r1 = r;
t1 = new Thread(this);
t1.start();
}
public void run ()
{
while (true)
{
if(r1.get_flag () == false)
{
synchronized(r1)
{
r1.increment_decrement("Producer",true);
}
}
}
}
public void waitForThread () throws InterruptedException
{
t1.join ();
}
}
class consumer implements Runnable
{
resource r2;
Thread t2;
consumer(resource r)
{
r2 = r;
t2 = new Thread (this);
t2.start();
}
public void run()
{
while (true)
{
if(r2.get_flag () == true)
{
synchronized(r2)
{
r2.increment_decrement("Consumer",false);
}
}
}
}
public void waitForThread () throws InterruptedException
{
t2.join ();
}
}
public class producercon
{
public static void main(String args[])
{
try
{
System.out.print("PRESS CTRL+C TO TERMINATE\n");
resource r = new resource();
consumer c = new consumer(r);
producer p = new producer(r);
c.waitForThread ();
p.waitForThread ();
}
catch(InterruptedException e)
{
}
}
}