使用BlockingQueue实现的生产者和消费者

使用Java BlockingQueue实现的生产者和消费者

1.定义生产者


class Producer implements Runnable {

    private BlockingQueue<String> queue;
    private String id;

    private volatile boolean isRunning = true;
    private static AtomicInteger count = new AtomicInteger();

    public Producer(BlockingQueue<String> queue, String id) {
        this.queue = queue;
        this.id = id;
    }

    public void stop() {
        isRunning = false;
    }

    @Override
    public void run() {

        String data = null;
        try {
            while (isRunning) {
                System.out.println("PRODUCER: " + id + " is running");
                Thread.sleep(100);

                data = "data:" + count.incrementAndGet();
                System.out.println("Thread: " + id + " procedued data into queue: " + data + " ...");
                if (!queue.offer(data, 2, TimeUnit.SECONDS)) {
                    System.out.println("failed to put data into queue: " + data);
                }
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
            Thread.currentThread().interrupt();
        } finally {
            System.out.println("Thread: " + id + " quit from producer thread");
        }
    }
}

2.定义消费者


class Consumer implements Runnable {

    /**
     * 用util.concurrent.BlockingQueue沟通生产者和消费者的桥梁
     */
    private BlockingQueue<String> queue;
    private String id;


    private volatile boolean isRunning = true;

    public Consumer(BlockingQueue<String> queue, String id) {
        this.queue = queue;
        this.id = id;
    }

    public void stop() {
        isRunning = false;
    }

    @Override
    public void run() {
        System.out.println("Thread: " + id + " Consumer thread is running...");
        boolean isRunning = true;
        try {
            while (isRunning) {
                System.out.println("Thread: " + id + " fetch data from linkedQueue..." + " queue size: " + queue.size());
                /*
                 * 从队列里取出一个元素,2秒超时,如果两秒之后还没有东西可以取,则poll返回null
                 */
                String data = queue.poll(2, TimeUnit.SECONDS);
                if (null != data) {
                    System.out.println("Thread: " + id + " has consumed one data from queue: " + data
                            + "   Queue sise: " + queue.size());
                    // simulate data consumption
                    Thread.sleep(1000);
                } else {
                    isRunning = false;
                    // 消费者准备退出
                    System.out.println("Thread: " + id + " Consumer read queue timeout");
                }
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
            Thread.currentThread().interrupt();
        } finally {
            System.out.println("Thread: " + id + " consumer thread ends");

        }
    }
}

3,测试


import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;


public class TaskProductFactory {

    public static void main(String args[]) throws InterruptedException {

        BlockingQueue<String> queue = new LinkedBlockingQueue<>(15);

        Producer producer1 = new Producer(queue, "PROD1");
        Producer producer2 = new Producer(queue, "PROD2");
        Producer producer3 = new Producer(queue, "PROD3");
        Consumer consumer1 = new Consumer(queue, "CONSUMER1");
        Consumer consumer2 = new Consumer(queue, "CONSUMER2");

        java.util.concurrent.ExecutorService service = Executors.newCachedThreadPool();

        service.execute(producer1);
        service.execute(producer2);
        service.execute(producer3);
        service.execute(consumer1);
        service.execute(consumer2);

        Thread.sleep(3 * 1000);
        producer1.stop(); // 一定要先关闭生产者
        producer2.stop();
        producer3.stop();
        consumer1.stop();
        consumer2.stop();

        Thread.sleep(2000);
        service.shutdown();
    }
}

Thread: CONSUMER1 has consumed one data from queue: data:19   Queue sise: 5
Thread: CONSUMER2 has consumed one data from queue: data:20   Queue sise: 4
Thread: CONSUMER1 fetch data from linkedQueue... queue size: 4
Thread: CONSUMER2 fetch data from linkedQueue... queue size: 4
Thread: CONSUMER2 has consumed one data from queue: data:22   Queue sise: 2
Thread: CONSUMER1 has consumed one data from queue: data:21   Queue sise: 2
Thread: CONSUMER1 fetch data from linkedQueue... queue size: 2
Thread: CONSUMER2 fetch data from linkedQueue... queue size: 2
Thread: CONSUMER1 has consumed one data from queue: data:24   Queue sise: 1
Thread: CONSUMER2 has consumed one data from queue: data:23   Queue sise: 0
Thread: CONSUMER1 fetch data from linkedQueue... queue size: 0
Thread: CONSUMER2 fetch data from linkedQueue... queue size: 0
Thread: CONSUMER1 Consumer read queue timeout
Thread: CONSUMER2 Consumer read queue timeout
Thread: CONSUMER2 consumer thread ends
Thread: CONSUMER1 consumer thread ends

可以把公共资源抽取出来


import lombok.SneakyThrows;

import java.util.Random;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;

//公共资源
public class ShareResource {


    private BlockingQueue<String> queue;
    private int capacity = 0;


    public ShareResource(int capacity) {
        this.capacity = capacity;
        queue = new LinkedBlockingQueue<>(capacity);
    }

    // 生产产品
    @SneakyThrows
    public void produce() {
        // 生产条件满足情况下,生产产品
        Random random = new Random();
        int i = random.nextInt();
        System.out.println("线程(" + Thread.currentThread().getName() + ")生产了一件产品: " + i + ";当前剩余商品" + queue.size() + "个");
        queue.add(String.valueOf(i));
    }


    // 消费产品
    @SneakyThrows
    public void consume() {
        String product = queue.take();
        System.out.println("线程(" + Thread.currentThread().getName() + ")消费了一件产品:" + product + ";当前剩余商品" + queue.size() + "个");
    }
}


class Producer implements Runnable {

    private ShareResource shareResource;

    public Producer(ShareResource shareResource) {
        this.shareResource = shareResource;
    }

    @Override
    public void run() {
        try {
            while (true) {
                shareResource.produce();
                Thread.sleep(500);
            }
        } catch (InterruptedException e1) {
            e1.printStackTrace();
        }
    }
}

/**
 * 消费者
 */
class Consumer implements Runnable {

    private ShareResource shareResource;

    public Consumer(ShareResource shareResource) {
        this.shareResource = shareResource;
    }

    @Override
    public void run() {
        while (true) {
            shareResource.consume();
        }
    }

    public static void main(String[] args) {


        java.util.concurrent.ExecutorService service = Executors.newCachedThreadPool();

        ShareResource shareResource = new ShareResource(5);
        Producer producer1 = new Producer(shareResource);
        Producer producer2 = new Producer(shareResource);

        Consumer consumer1 = new Consumer(shareResource);
        Consumer consumer2 = new Consumer(shareResource);
        Consumer consumer3 = new Consumer(shareResource);


        service.execute(producer1);
        service.execute(producer2);

        service.execute(consumer1);
        service.execute(consumer2);
        service.execute(consumer3);


    }

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值