用 wait-notify 写一段代码来解决生产者-消费者问题

Posted xbq8080

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了用 wait-notify 写一段代码来解决生产者-消费者问题相关的知识,希望对你有一定的参考价值。

在同步块中调用 wait() 和 notify()方法,如果阻塞,通过循环来测试等待条件。请参考答案中的示例代码。

【生产者】

import java.util.Vector;
import java.util.logging.Level;
import java.util.logging.Logger;

public class Producer implements Runnable {

    private final Vector sharedQueue;
    private final int SIZE;

    public Producer(Vector sharedQueue, int size) {
        this.sharedQueue = sharedQueue;
        this.SIZE = size;
    }

    @Override
    public void run() {
        // 生产数据
        for (int i = 0; i < 7; i++) {
            System.out.println("Produced:" + i);
            try {
                produce(i);
            } catch (InterruptedException ex) {
                Logger.getLogger(Producer.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }

    private void produce(int i) throws InterruptedException {

        // wait if queue is full
        while (sharedQueue.size() == SIZE) {
            synchronized (sharedQueue) {
                System.out.println("Queue is full " + Thread.currentThread().getName()
                        + " is waiting , size: " + sharedQueue.size());
                sharedQueue.wait();
            }
        }

        // producing element and notify consumers
        synchronized (sharedQueue) {
            sharedQueue.add(i);
            sharedQueue.notifyAll();
        }
    }
}

【消费者】

import java.util.Vector;
import java.util.logging.Level;
import java.util.logging.Logger;

public class Consumer implements Runnable {

    private final Vector sharedQueue;
    private final int SIZE;

    public Consumer(Vector sharedQueue, int size) {
        this.sharedQueue = sharedQueue;
        this.SIZE = size;
    }

    @Override
    public void run() {
        // 消费数据
        while (true) {
            try {
                System.out.println("Consumer: " + consume());
                Thread.sleep(50);
            } catch (InterruptedException ex) {
                Logger.getLogger(Consumer.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }

    private int consume() throws InterruptedException {

        // wait if queue is empty
        while (sharedQueue.isEmpty()) {
            synchronized (sharedQueue) {
                System.out.println("Queue is empty " + Thread.currentThread().getName()
                        + " is waiting , size: " + sharedQueue.size());
                sharedQueue.wait();
            }
        }

        //otherwise consume element and notify waiting producer
        synchronized (sharedQueue) {
            sharedQueue.notifyAll();
            return (Integer) sharedQueue.remove(0);
        }
    }
}

【测试函数】

import java.util.Vector;

public class ProducerConsumerSolution {

    public static void main(String[] args) {
        Vector sharedQueue = new Vector();
        int size = 4;
        Thread prodThread = new Thread(new Producer(sharedQueue, size), "Producer");
        Thread consThread = new Thread(new Consumer(sharedQueue, size), "Consumer");
        prodThread.start();
        consThread.start();
    }
}

运行结果:

Produced:0
Queue is empty Consumer is waiting , size: 0
Produced:1
Consumer: 0
Produced:2
Produced:3
Produced:4
Produced:5
Queue is full Producer is waiting , size: 4
Consumer: 1
Produced:6
Queue is full Producer is waiting , size: 4
Consumer: 2
Consumer: 3
Consumer: 4
Consumer: 5
Consumer: 6
Queue is empty Consumer is waiting , size: 0

 

以上是关于用 wait-notify 写一段代码来解决生产者-消费者问题的主要内容,如果未能解决你的问题,请参考以下文章

synchronized VS Lock, wait-notify VS Condition

线程间通信与协作方式之——wait-notify机制

用vs来写一段判断是不是水仙花数的代码

java 怎么通过写一段代码来判断端口号是不是被占用。在Linux下。

如何用C或c++写一段代码读取xsd结构生成一个XML文件,现在我有数据文件和XSD文件

用VC++写一段程序,主要功能如下:释放两个文件,去掉系统文件保护。运行其中的一个程序