多线程生产消费模式简单实例

有一道这样的题目,用多线程方式实现生产者消费者模式,生产者随便产生一个0-1000之间的数,消费者打印出生产的数据。当随机产生的数是0时,生产线程和消费线程都退出。

思路:用一个队列Queue存储产生的数据,队列作为共享数据在生产者和消费者共享。

生产者:

/**
*数据生产者
 */

import java.util.Queue;
import java.util.Random;

/**
 * 名称:类的中文名称 <br>
 * 功能:对类的功能进行说明 <br/>
 * <br/>
 *
 * @since JDK 1.7
 * @see
 * @author rdf
 */
public class ProducerNum implements Runnable {
    private Queue q;

public ProducerNum(Queue q) {
        this.q = q;
    }

@Override
    public void run() {
        Random random = new Random();
        int count = 0;
        while (true) {
            int i = random.nextInt(10);
            if (i != 0) {
                count++;
                q.add(i);
                System.out.println(i);
                try {
                    Thread.sleep(1000);
                }
                catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            else {
                q.add(i);
                System.out.println("这是第" + count + "次" + ":" + i);
                break;
            }
        }
    }

}

消费者:

/**
*消费数据
 */

package pcmodl;

import java.util.Queue;

/**
 * 名称:类的中文名称 <br>
 * 功能:对类的功能进行说明 <br/>
 * <br/>
 *
 * @since JDK 1.7
 * @see
 * @author rdf
 */
public class ConsumerNom implements Runnable {
    private Queue q;

/**
     * 构造方法: ConsumerNom.
     *
     */
    public ConsumerNom(Queue q) {
        this.q = q;
    }

@Override
    public void run() {
        while (true) {
            if (!q.isEmpty()) {
                if ((int) q.peek() == 0) {
                    System.out.println(q.peek());
                    break;
                }
                System.out.println(q.poll());
                System.out.println("************");
                try {
                    Thread.sleep(1000);
                }
                catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            else {
            }
        }

}

}

主线程:

/**
 *主线程
 */

package pcmodl;

import java.util.LinkedList;
import java.util.Queue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * 名称:类的中文名称 <br>
 * 功能:对类的功能进行说明 <br/>
 * <br/>
 *
 * @since JDK 1.7
 * @see
 * @author rdf
 */
public class ProduceConsumer {

/**
     * <b>名称</b>:方法的中文名称 <br/>
     * <br/>
     * <b>说明</b>:说明方法的功能和使用要点 <br/>
     * <br/>
     *
     * @param args
     *
     * @see
     */

public static void main(String[] args) {
        Queue q = new LinkedList<>();
        ExecutorService service = Executors.newCachedThreadPool();//使用newCachedThreadPool线程池
        ProducerNum p = new ProducerNum(q);
        ConsumerNom c = new ConsumerNom(q);
        // Thread t1 = new Thread(p);
        // Thread t2 = new Thread(c);
        // t1.start();
        // t2.start();
        service.submit(p);
        service.submit(c);
    }

}

总结:程序在执行时,消费者线程老是无故结束,不在执行,由于本人对多线程学习不够深,不明白为什么出现这种情况。个人猜测是应为数据共享是线程阻塞造成的。

public class ConsumerNom implements Runnable {
    private Queue q;

/**
     * 构造方法: ConsumerNom.
     *
     */
    public ConsumerNom(Queue q) {
        this.q = q;
    }

@Override
    public void run() {
        while (true) {
            if (!q.isEmpty()) {
                if ((int) q.peek() == 0) {
                    System.out.println(q.peek());
                    break;
                }
                System.out.println(q.poll());
                System.out.println("************");
                try {
                    Thread.sleep(1000);
                }
                catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            else {//消费者增加这样一段代码,进过测试,没有出现上述问题。
                try {
                    Thread.sleep(500);
                }
                catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }

}

线程类也可以集成Thread类:

生产者:

public class ProducerNum extends Thread {
    private Queue q;

public ProducerNum(Queue q) {
        this.q = q;
    }

@Override
    public void run() {
        Random random = new Random();
        int count = 0;
        while (true) {
            int i = random.nextInt(10);
            if (i != 0) {
                count++;
                q.add(i);
                System.out.println(i);
                try {
                    Thread.sleep(1000);
                }
                catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            else {
                q.add(i);
                System.out.println("这是第" + count + "次" + ":" + i);
                break;
            }
        }
    }

}

消费者:

public class ConsumerNom extends Thread {
    private Queue q;

/**
     * 构造方法: ConsumerNom.
     *
     */
    public ConsumerNom(Queue q) {
        this.q = q;
    }

@Override
    public void run() {
        while (true) {
            if (!q.isEmpty()) {
                if ((int) q.peek() == 0) {
                    System.out.println(q.peek());
                    break;
                }
                System.out.println(q.poll());
                System.out.println("************");
                try {
                    Thread.sleep(1000);
                }
                catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            else {
                try {
                    Thread.sleep(500);
                }
                catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }

}

}

时间: 2024-11-05 16:16:26

多线程生产消费模式简单实例的相关文章

Java 多线程ServerSocket通讯简单实例(基于TCP协议)

首先是建立一个类继承Thread类 package com.zzq.socket;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import java.io.OutputStream;import java.io.PrintWriter;import java.net.Socket; public class

Java 多线程 简单实例 (消费者与生成者)的关系

PS::线程这套东西在PHP里完全是不存在的概念,有待进一步的学习: PS::这个实例是根据书本上的知识进行扩展的,理解程度50%左右吧! 1.定义生产消费环境 package second; public class Queue { int value = 0; boolean isEmpty = true; /** * 生产者 * @param v */ public synchronized void put(int v){ if(!isEmpty){//如果存在数据没有被消费 try{

Java的多线程实现生产/消费模式

Java的多线程实现生产/消费模式 在Java的多线程中,我们经常使用某个Java对象的wait(),notify()以及notifyAll() 方法实现多线程的通讯,今天就使用Java的多线程实现生产/消费模式,需求如下: 线程A ProductThread 继承Thread 实现生产数据 若线程共享的数据不为NULL,则生产线程进入等待状态 线程B CustomThread 继承Thread 实现消费数据(输出到控制台) 当线程共享数据为NULL的时候,进入等待状态 线程B 消费完数据之后,

Cr多线程编程简单实例

国家using System; using System.Collections;using System.Collections.Generic;using System.Threading; /// <summary>/// 在开发中经常会遇到线程的例子,如果某个后台操作比较费时间,我们就可以启动一个线程去执行那个费时的操作,同时程序继续执行.在某些情况下可能会出现多个线程的同步协同的问题,下面的例子就展示了在两个线程之间如何协同工作.//////这个程序的思路是共同做一件事情(从一个Ar

使用C#的泛型队列Queue实现生产消费模式

本篇体验使用C#的泛型队列Queue<T>实现生产消费模式. 如果把生产消费想像成自动流水生产线的话,生产就是流水线的物料,消费就是某种设备对物料进行加工的行为,流水线就是队列. 现在,要写一个体现生产消费模式的泛型帮助类,比如叫ProducerConsumer<T>. 该类肯定会维护一个有关生产.物料的Queue<T>类型的字段,还存在一个有关消费.Action<T>类型的字段. 在ProducerConsumer类的构造函数中,为Action<T&

java多线程 生产消费者模型

[seriesposts sid=500] 下面的代码讲述了一个故事 一个面包生产铺里目前有30个面包,有三个人来买面包,第一个人要买50个,第二个要买20个,第三个要买30个. 第一个人不够,所以等着,让第二个买了.面包铺继续生产面包.有7个人在生产. package com.javaer.thread; public class CPMode { public static void main(String[] args) { Godown godown = new Godown(30);

JAVA RMI远程方法调用简单实例[转]

RMI的概念 RMI(Remote Method Invocation)远程方法调用是一种计算机之间利用远程对象互相调用实现双方通讯的一种通讯机制.使用这种机制,某一台计算机上的对象可以调用另外 一台计算机上的对象来获取远程数据.RMI是Enterprise JavaBeans的支柱,是建立分布式Java应用程序的方便途径.在过去,TCP/IP套接字通讯是远程通讯的主要手段,但此开发方式没有使用面向对 象的方式实现开发,在开发一个如此的通讯机制时往往令程序员感觉到乏味,对此RPC(Remote

WPF单线程定时器 简单实例

//窗体加载完毕 void MyMessageBox_Loaded(object sender, RoutedEventArgs e) { //启动定时期倒计时,多线程计时 //System.Threading.Timer timer: //启动单线程计时 System.Windows.Threading.DispatcherTimer timer = new System.Windows.Threading.DispatcherTimer(); timer.Interval = new Tim

异步简析之BlockingCollection实现生产消费模式

目前市面上有诸多的产品实现队列功能,比如Redis.MemCache等... 其实c#中也有一个基础的集合类专门用来实现生产/消费模式 (生产模式还是建议使用Redis等产品) 下面是官方的一些资料和介绍: BlockingCollection是一个线程安全集合类,可提供以下功能: 实现制造者-使用者模式. 通过多线程并发添加和获取项. 可选最大容量. 集合为空或已满时通过插入和移除操作进行阻塞. 插入和移除"尝试"操作不发生阻塞,或在指定时间段内发生阻塞. 封装实现 IProduce