`

生产者/消费者 JAVA

阅读更多

关键字: 线程
   原文:

The producer/Consumer Example

http://life.csu.edu.au/java-tut/essential/threads/synchronization.html



    在这个例子中,生产者产生整数0-9存储到Cubblyhole。为了使同步问题更有趣,生产者的生产周期为0-100ms.



Cubblehole.java

Java代码
public class CubbyHole {  
    private int contents;  
    private boolean available = false;  
      
    public synchronized int get(int who) {  
        while (!available) {  
            try {  
                wait();  
            } catch (InterruptedException e) {  
                e.printStackTrace();  
            }  
        }  
          
        available = false;  
        System.out.format("Consumer %d got: %d%n", who, contents);  
        notifyAll();  
        return contents;  
    }  
      
    public synchronized void put(int who, int value) {  
        while (available) {  
            try {  
                wait();  
            } catch (InterruptedException e) {  
                e.printStackTrace();  
            }  
        }  
        contents = value;  
        available = true;  
        System.out.format("Producer %d put: %d%n", who, contents);  
        notifyAll();  
    }  


public class CubbyHole {
private int contents;
private boolean available = false;

public synchronized int get(int who) {
while (!available) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}

available = false;
System.out.format("Consumer %d got: %d%n", who, contents);
notifyAll();
return contents;
}

public synchronized void put(int who, int value) {
while (available) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
contents = value;
        available = true;
        System.out.format("Producer %d put: %d%n", who, contents);
        notifyAll();
}
}

生产者 Producer.java

Java代码
public class Producer extends Thread {  
    private CubbyHole cubbyhole;  
 
    private int number;  
 
    public Producer(CubbyHole c, int number) {  
        cubbyhole = c;  
        this.number = number;  
    }  
 
    public void run() {  
        for (int i = 0; i < 10; i++) {  
            cubbyhole.put(number, i);  
            try {  
                sleep((int) (Math.random() * 100));  
            } catch (InterruptedException e) {  
            }  
        }  
    }  


public class Producer extends Thread {
private CubbyHole cubbyhole;

private int number;

public Producer(CubbyHole c, int number) {
cubbyhole = c;
this.number = number;
}

public void run() {
for (int i = 0; i < 10; i++) {
cubbyhole.put(number, i);
try {
sleep((int) (Math.random() * 100));
} catch (InterruptedException e) {
}
}
}
}




当CubbyHole可以消费时,消费者消费CubbyHole中的整数。



消费者 Consumer.java

Java代码
public class Consumer extends Thread {  
    private CubbyHole cubbyhole;  
 
    private int number;  
 
    public Consumer(CubbyHole c, int number) {  
        cubbyhole = c;  
        this.number = number;  
    }  
 
    public void run() {  
        int value = 0;  
        for (int i = 0; i < 10; i++) {  
            value = cubbyhole.get(number);  
        }  
    }  


public class Consumer extends Thread {
private CubbyHole cubbyhole;

private int number;

public Consumer(CubbyHole c, int number) {
cubbyhole = c;
this.number = number;
}

public void run() {
int value = 0;
for (int i = 0; i < 10; i++) {
value = cubbyhole.get(number);
}
}

生产者和消费者共享CubbyHole对象的数据。理想上消费者一个个取得生产者生产的值,但是无论怎么样努力都不能保证这种正确数据。假定这种情况,这两个线程都没有同步;我们讨论可能会发生的潜在的错误。



第一个是,生产者的速度比消费者快,连续产生两个数字,使消费者没有取到第一个数字。这种情况下,消费者丢失了一个数字。如下图。





Consumer misses number.



另一个是,消费者的速度比生产者快,两次消费了同一个值。如下图。








Consumer gets the same number twice.



不管怎么样,这个结果是错误的,是因为消费者应该得到每一个生产者生产的数。这种情况称为竞态条件。竞态是两个或两个以上线程或者进程读或写同一个数据,处理结果依赖于线程执行时间的安排。竞态条件会产生不可预知的结果和细小的程序错误。竞态条件在这个实例中通过同步生产者存储数值到CubbyHole和消费者从CubbyHole取得数值。这种同步行为必须从两个方面同步。

第一,这两个线程不能同时使用CubbyHole。线程可能通过锁一个对象来阻止另一个线程访问。当然一个线程锁了一个对象,另一个线程尝试调用同一个对象的同步方法。第二个线程将会被阻塞直接第一个线程解锁。

第二,这两个线程必须有简单的沟通。沟通的方法是,生产者必须有方法指示消费者,产品已经生产好,等待消费,消费也必须有方法指示生产者,产品已经消费完。java对象已经提供一些方法--wait, notify, and notifyAll -- 帮助线程以特定的条件等待和通知其它线程条件已经改变。



分享到:
评论

相关推荐

    由生产者/消费者问题看JAVA多线程

    ### 由生产者/消费者问题深入理解JAVA多线程 #### 生产者/消费者问题概述 生产者/消费者问题是一个经典的计算机科学问题,用于展示进程间的通信与同步问题。在这个模型中,生产者负责创建数据并将其放置到共享内存...

    操作系统课程设计——生产者消费者问题Java图形界面动态演示

    设计目的:通过研究Linux 的进程机制和信号量实现生产者消费者问题的并发控制。说明:有界缓冲区内设有20 个存储单元,放入/取出的数据项设定为1‐20 这20 个整型数。设计要求:1)每个生产者和消费者对有界缓冲区...

    架构设计 -- 生产者/消费者模式

    在Java中,可以使用`java.util.concurrent`包中的`BlockingQueue`来实现这个模式,它提供了线程安全的队列操作,可以很好地控制生产者和消费者的并发行为。 在寄信的例子中,生产者对应写信的人,他负责生成信件...

    java kafka 生产者/消费者demo

    Java Kafka 生产者/消费者Demo详解 在分布式消息系统中,Apache Kafka是一个高效、可扩展且高可用的数据流平台,广泛应用于实时数据处理和大数据领域。Kafka通过使用主题(Topics)和分区(Partitions)的概念,...

    生产者/消费者模式 阻塞队列 LinkedBlockingQueue

    在Java中,阻塞队列(BlockingQueue)是一个很好的实现生产者/消费者模式的工具,而LinkedBlockingQueue则是Java并发包(java.util.concurrent)中提供的一个具体实现。 LinkedBlockingQueue是一个基于链表结构的...

    多线程模拟实现生产者/消费者模型

    这个模型的核心思想是将生产者和消费者分隔开,使得生产者可以专注于创建产品,而消费者则专注于消耗这些产品,两者之间通过一个共享的数据缓冲区进行通信。 在Java等支持多线程的编程语言中,我们可以使用`Thread`...

    C++ PV操作(生产者/消费者)简单实例

    ### C++ PV操作(生产者/消费者)简单实例解析 #### 概述 在多线程编程中,生产者-消费者问题是一个经典的同步问题。它描述了一组生产数据的线程(生产者)和一组消费这些数据的线程(消费者)。为了确保线程间的...

    生产者消费者JAVA课程设计

    //下面的消费者类对象和生产者类对象所操作的是同一个同步堆栈对象 Producer p1 = new Producer(stack,ce); new Thread(p1).start();//生产者线程启动 Consumer c1 = new Consumer(stack,ce); new Thread(c1)....

    java多线程实现生产者和消费者

    在并发编程中,"生产者-消费者"模式是一种经典的解决问题的范式,用于协调两个或更多线程间的协作,其中一部分线程(生产者)生成数据,另一部分线程(消费者)消费这些数据。 生产者-消费者模型的核心在于共享资源...

    生产者与消费者 java实现

    本主题将深入探讨生产者与消费者模型的Java实现。 生产者与消费者问题的核心是有一个共享资源(例如,一个缓冲区),生产者不断地生产产品并放入缓冲区,而消费者则从缓冲区取出产品进行消费。关键在于确保生产者...

    java生产者消费者图形界面模拟

    在Java编程中,"生产者消费者图形界面模拟"是一个经典的多线程问题的实例,它展示了如何通过并发处理来优化资源的使用。这个课程设计基于Java Swing库构建了一个图形用户界面(GUI),用于演示和理解生产者消费者...

    Java多线程实现生产者消费者

    这就是一个基本的Java“生产者-消费者”模型实现。通过这样的设计,我们可以有效地控制生产者和消费者的执行顺序,确保了数据的正确性,并且避免了先消费后生产的情况。在实际应用中,可能需要根据具体需求进行优化...

    java 生产者消费者问题(源码)

    Java生产者消费者问题是多线程编程中的一个经典案例,它主要展示了如何通过共享资源来实现线程间的协作。这个问题源于现实生活中的生产流水线,其中生产者负责制造产品,而消费者负责消耗这些产品。在计算机系统中,...

    Java生产者与消费者

    在Java编程中,"生产者与消费者"模式是一种经典的多线程问题,它涉及到了并发处理和资源管理。这个模式的核心思想是通过共享一个有限的缓冲区,使得生产者线程可以将产品放入缓冲区,而消费者线程则可以从缓冲区取出...

    java生产者与消费者实验报告

    ### Java生产者与消费者模型详解 #### 实验背景与目的 在并发编程中,生产者-消费者模式是一种经典的解决同步问题的设计模式。本实验旨在通过实际编程操作,深入理解Java中生产者与消费者模型的工作机制及其同步...

    java生产者消费者

    Java生产者消费者模式是一种多线程设计模式,它在并发编程中被广泛使用,用于解决资源的共享问题。在这个模式中,"生产者"负责创建数据,而"消费者"则负责处理这些数据。它们通过一个共享的数据缓冲区进行通信,避免...

    《生产者/消费者循环》后续资源包.zip

    《生产者/消费者循环》后续资源包.zip是一个包含多种级别技术教程、实例代码及前沿技术文档的综合学习资源。这个压缩包旨在帮助学习者深入理解并应用生产者/消费者模型,这一模型是并发编程中的重要概念,广泛应用...

    java生产者消费者问题

    Java生产者消费者问题是多线程编程中的一个经典问题,它主要涉及到线程间的协作与通信。在并发编程中,生产者负责生成数据,而消费者则负责处理这些数据。为了解决生产者和消费者之间的问题,Java提供了一系列的同步...

    Java 生产者消费者模式

    在Java编程中,生产者消费者模式是一种典型的多线程协作模型,用于解决系统资源供需不平衡的问题。这个模式的核心思想是将生产数据和消费数据的过程解耦,使得生产者可以独立地生产数据,而消费者可以独立地消费数据...

    java多线程生产者消费者问题示例

    java多线程学习,生产者消费者问题示例

Global site tag (gtag.js) - Google Analytics