【发布时间】:2012-01-16 21:45:09
【问题描述】:
在下面的代码中,当我执行producercon 类时,有时执行会卡住,看起来像死锁。但是,如果我使get_flag () 同步,那么就不存在这样的问题。
我不知道怎么会有问题。 flag 可以为真或假,因此只有producer 或consumer 之一将进入if 语句。在其中一个进入if 后,它将使用对象r 进入监视器(两者都使用相同的对象引用进行初始化)。唯一可能发生的问题是increment_decrement () 函数调用正在修改r 对象,而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)
{
}
}
}
【问题讨论】:
-
在一个完全不相关的注释中,你真的应该用大写的第一个字母来命名你的类:Producer、Consumer、Resource...
-
@OlivierCroisier:同意,(我一个朋友的代码,贴出原文)
标签: java synchronization synchronized