使用wait()和notifyAll()设置和获取方法

时间:2013-02-15 13:46:29

标签: java multithreading buffer

我不知道为什么我的get方法不起作用。它返回“”。

我有使用此类的Producer和Consumer类以及只有set和get方法的Buffer接口。生产者从文件读取和消费者写入另一个文件。 Producer和Consumer都使用线程。

请帮帮我。提前谢谢。

import java.util.Stack;

public class synchronizedFile implements Buffer {

public Stack<String> StackBuffer = new Stack<String>();

public void set(String value) {

    synchronized (StackBuffer) {
        if (StackBuffer.size() <= 15) {
            StackBuffer.push(value);
            System.out.println(StackBuffer.toString());
            StackBuffer.notifyAll();
            System.out.println("Consumer notify");
        } else {
            try {

                System.out.println("Produser is waitting--------------------------------");
                StackBuffer.wait();
                System.out.println("Consumer tries to write");
                set(value);

            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}

public String get() throws InterruptedException {

    String Flag = " ";
    synchronized (StackBuffer) {
        if (!StackBuffer.isEmpty()) {

            Flag = StackBuffer.firstElement();
            StackBuffer.remove(StackBuffer.firstElement());
            StackBuffer.notifyAll();
            System.out.println("Producer notify");
            return Flag;
        } else {
            StackBuffer.wait();
            System.out.println("Consumer is waitting --------------------");
            get();

        }

    }

    return Flag;

}

}

3 个答案:

答案 0 :(得分:1)

您至少错过了get()方法的Flag = get()分支中的else

除了考虑使用BlockingQueue之外,java.util.concurrent中还有一些实现可以帮助您完成并发编程。使用低级构造waitnotify容易出错。如果没有彻底检查,如果您的实施是正确的,我会感到惊讶。

答案 1 :(得分:1)

您等待并通知两种不同的状态:已满和空。因此,您必须使用两个单独的锁定对象。很久以前就已经涵盖了here

基本上,如果您没有为了使用Stack类或某种赋值而实现它,请使用java.util.concurrent中的BlockingQueue。

答案 2 :(得分:0)

在这里,你递归地调用get(),但扔掉它的结果:

StackBuffer.wait();
System.out.println("Consumer is waitting --------------------");
get();

Flag = get();return get();之类的内容会更合适。

(另外,我不确定在执行synchronized两次进入wait部分是否有效。也许是,我只是不确定。)