java线程的小问题

来源:百度知道 编辑:UC知道 时间:2024/05/13 16:53:21
public class BufferLock //加互斥锁的缓冲区
{
private int value; //共享变量
private boolean isEmpty = true; //value是否为空的信号量

public synchronized void put(int i) //同步方法
{
while (!isEmpty) //当value不空时,等待
{
try
{
this.wait(); //使调用该方法的当前线程等待,即阻塞自己
}
catch(InterruptedException e) {}
}

value = i; //当value空时,value获得值
isEmpty = false; //设置value为不空状态
notify(); //唤醒其他等待线程
}

public synchronized int get() //同步方法
{
while (isEmpty) //当value空时,等待
{
try
{
this.wait();
}

首先说明,你的程序逻辑并没有问题,只是 System.out.println 放置的位置有些问题。
你可能对于下面的输出结果感到有些困惑:

Sender put : 1
Receiver get : 1
Sender put : 2
Sender put : 3
Receiver get : 2
Receiver get : 3
Receiver get : 4
Sender put : 4
Sender put : 5
Receiver get : 5

我起初也是,但是仔细琢磨了一下,发生这样的问题的原因如下:
首先要说明的是:哪个线程先获得 System.out 对象在打印字符串的时候就会先输出到控制台。
因为你的语句:
System.out.println("\t\t\tReceiver get : " + buffer.get()) ;
执行该语句会先执行:buffer.get(),然后再执行控制台输出。所以在 执行完 get() 中的唤醒语句后,还会有一个时间空隙来执行输出。
这就给 put 线程时间可以执行。
所以就有可能会输出上面的结果,我修改了一下 打印语句的位置,这次会严格按照你预想的进行输出:

public class MyBufferLock
{
private int value; //共享变量
private boolean isEmpty = true; //value是否为空的信号量

public synchronized void put(int i) //同步方法
{
// System.out.println("int put i=" + i );
while (!isEmpty) //当value不空时,等待
{
try
{
// S