用 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

原文地址:https://www.cnblogs.com/xbq8080/p/10371214.html

时间: 2024-11-04 11:36:05

用 wait-notify 写一段代码来解决生产者-消费者问题的相关文章

PHP写一段代码,确保多个进程同时写入一个文件成功

这个需求是在软件设计过程常见的加锁.学计算机的同学都应该知道,这个是在<计算机操作系统>课程上有这个知识点.主要要考虑的是进程的同步,也就是进程对资源的互斥访问.OK,用程序说话吧! <?phpfunction writefile( $filename, $data ){ $fp = fopen( $filepath, 'a' );   //以追加的方式打开文件,返回的是指针 do{   usleep( 100 );  //暂停执行程序,参数是以微秒为单位的 }while( !flock

假设写一段代码引导PC开机这段代码是 ? Here is a tiny &amp;quot;OS&amp;quot; :-D

Hello world -- OS 我找到了华科绍志远博士的相关代码,发现他依据MIT的JOS的boot.S 稍作改动.然后单独剥离出来,能够非常好玩~ 资料下载地址: http://download.csdn.net/detail/u011368821/8006465 原则上仅仅须要两个文件(boot.S mmu.h)就能够,可是我们这里还须要一些附带的虚拟器工具.以及makefile来做实验. 须要提示的就是地址0xb800是显存的开头地址 : ) MOVSB(MOVe String Byt

用for循环写这段代码

之前用while循环写了一段代码,现在改为用for循环来写,代码如下: hongtao_age = 38 for i in range(5): guess_age = int(input("Please guess the hongtao's age: ")) if guess_age == hongtao_age: print("================") print("Yes!you get it!!Good Bye!!") pri

如果写一段代码引导PC开机这段代码是 ? Here is a tiny &quot;OS&quot; :-D

Hello world -- OS 我找到了华科绍志远博士的相关代码,发现他根据MIT的JOS的boot.S 稍作修改,然后单独剥离出来,可以很好玩~ 资料下载地址: http://download.csdn.net/detail/u011368821/8006465 原则上只需要两个文件(boot.S mmu.h)就可以,但是我们这里还需要一些附带的虚拟器工具,以及makefile来做实验. 需要提示的就是地址0xb800是显存的开头地址 : ) MOVSB(MOVe String Byte)

day2:写几段代码

在linux公社找到本书<Python核心编程 第二版> 跳过前面32页的啰七八嗦,看代码~ 字符串替换 >>> print "%s's price is %d yuan" % ( "this tomato" , 6 ) this tomato's price is 6 yuan %s和%d是来占座的,分别占了字符串和整数的座.s代表string(字符串),d为啥代表整数我忘了-- 可以看出: 1.比起c++的printf,Python

编程题目:写一段代码,判断包含括号 { [ ( ) ] } 的表达式是否合法

先入和元素后判断,后入的元素先判断.这符合栈的特征. 所以这里可以利用栈实现括号合法性的判断. 1 #!/usr/bin/env python3 2 3 def judge(expression): 4 s = Stack() 5 d = {'}':'{', ']':'[', ')':'('} 6 for i in expression: 7 if i == '[' or i == '{' or i == '(': 8 s.push(i) 9 if i == ']' or i == '}' or

javascript 写一段代码,判断一个字符串中出现次数最多的字符串,并统计出现的次数

1 function test(){ 2 var bt = document.getElementById("bt"); 3 bt.addEventListener("click",function(){ 4 5 var str = "dafdsjkfnaiesdaadsllllllkkkkk444444444444444"; 6 var obj = []; // 存放结果集的数组,结果中存放 key-value 对象 7 for(var i =

解决写不出代码的方法

1.先分析实现的思路 拿到作业,按照要实现的功能,先分析去实现的思路.如果完全不知道该怎么去实现,一头雾水,最好先看看其他人事如何实现的,或者与老师或同学讨论.重点是要找到解决问题的办法,理清实现的思路.如果自己能想出几步来,那就先把这几步记录下来,然后重复上面的步骤. 2.把实现的思路边分析边记录下来. 在分析实现思路的时候,边分析,边写出来,使用中文写,写得详细点. 如果在编程工具里面写的话,直接写成注释,比如:第一步是要干上面第1.1要做什么第1.2要做什么第二步是要干上面第2.1要做什么

Java实现生产者消费者问题与读者写者问题

摘要: Java实现生产者消费者问题与读者写者问题 1.生产者消费者问题 生产者消费者问题是研究多线程程序时绕不开的经典问题之一,它描述是有一块缓冲区作为仓库,生产者可以将产品放入仓库,消费者则可以从仓库中取走产品.解决生产者/消费者问题的方法可分为两类:(1)采用某种机制保护生产者和消费者之间的同步:(2)在生产者和消费者之间建立一个管道.第一种方式有较高的效率,并且易于实现,代码的可控制性较好,属于常用的模式.第二种管道缓冲区不易控制,被传输数据对象不易于封装等,实用性不强. 同步问题核心在