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

Posted CoderRdf

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了多线程生产消费模式简单实例相关的知识,希望对你有一定的参考价值。

有一道这样的题目,用多线程方式实现生产者消费者模式,生产者随便产生一个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();
                }
            }
        }

    }

}

 

以上是关于多线程生产消费模式简单实例的主要内容,如果未能解决你的问题,请参考以下文章

生产者消费者模式的简单实现

java多线程基本概述——简单生产者消费者模式

生产者消费者模型:Kotlin 多线程读写文件实例

生产者消费者简单实现(转载)

多线程操作实例——生产者与消费者

python 多线程笔记-- 生产者/消费者模式(续)