首页 > 其他分享 >模拟生产者和消费者

模拟生产者和消费者

时间:2024-12-14 20:31:08浏览次数:3  
标签:消费者 Thread 生产者 getName System println public 模拟 out

1、使用“多线程&锁”模拟生产者和消费者

class ShareData {
    private int number = 0;
    private Lock lock = new ReentrantLock();
    private Condition condition = lock.newCondition();

    public void increment() throws Exception {
        lock.lock();
        try {
            //多线程的判断必须要用while
            while (number != 0) {
                //释放当前锁,进入等待状态,不能生产
                //唤醒线程从await()返回后需要重新获得锁
                condition.await();
            }
            //生产
            number++;
            System.out.println(Thread.currentThread().getName() + "\t" + number);
            //通知唤醒所有等待线程
            condition.signalAll();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

    public void decrement() throws Exception {
        lock.lock();
        try {
            //多线程的判断必须要用while
            while (number != 1) {
                //释放当前锁,进入等待状态,不能消费
                //唤醒线程从await()返回后需要重新获得锁
                condition.await();
            }
            //消费
            number--;
            System.out.println(Thread.currentThread().getName() + "\t" + number);
            //通知唤醒所哟等待线程
            condition.signalAll();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }
}

public class ProducerConsumer {
    public static void main(String[] args) {
        ShareData shareData = new ShareData();
        new Thread(()->{
            for (int i = 0; i < 10; i++) {
                try {
                    shareData.increment();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }, "A").start();

        new Thread(()->{
            for (int i = 0; i < 10; i++) {
                try {
                    shareData.decrement();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }, "B").start();
    }
}

2、使用“多线程&阻塞队列”模拟生产者和消费者

class ShareResource {
    //默认开启,进行生产+消费
    private volatile boolean FLAG = true;
    private AtomicInteger atomicInteger = new AtomicInteger();

    BlockingQueue<String> blockingQueue = null;

    public ShareResource(BlockingQueue<String> blockingQueue) {
        this.blockingQueue = blockingQueue;
        System.out.println(blockingQueue.getClass().getName());
    }

    public void produce() throws InterruptedException {
        String data = null;
        boolean retValue;
        while (FLAG) {
            data = atomicInteger.incrementAndGet() + "";
            retValue = blockingQueue.offer(data, 2L, TimeUnit.SECONDS);
            if (retValue) {
                System.out.println(Thread.currentThread().getName() + "\t 插入队列" + data + "成功");
            } else {
                System.out.println(Thread.currentThread().getName() + "\t 插入队列" + data + "失败");
            }
            TimeUnit.SECONDS.sleep(1);
        }
        System.out.println(Thread.currentThread().getName() + "\tFLAG=false,生产结束");
    }

    public void consume() throws InterruptedException {
        String data = null;
        while (FLAG) {
            data = blockingQueue.poll(2L, TimeUnit.SECONDS);
            if (null == data || data.equalsIgnoreCase("")) {
                FLAG = false;
                System.out.println(Thread.currentThread().getName() + "\t 超过2秒钟没有取到数据,消费退出");
                System.out.println();
                return;
            }
            System.out.println(Thread.currentThread().getName() + "\t消费数据" + data + "成功");
        }
    }

    public void stop() {
        this.FLAG = false;
    }
}

public class ProducerAndConsumer {

    public static void main(String[] args) throws InterruptedException {
        ShareResource shareResource = new ShareResource(new ArrayBlockingQueue<String>(10));
        new Thread(() -> {
            System.out.println(Thread.currentThread().getName() + "生产线程启动");
            try {
                shareResource.produce();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }, "Producer").start();

        new Thread(() -> {
            System.out.println(Thread.currentThread().getName() + "消费线程启动");
            try {
                shareResource.consume();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }, "Consumer").start();

        TimeUnit.SECONDS.sleep(5);
        System.out.println("5秒钟时间到,活动结束");

        shareResource.stop();
    }
}

  

标签:消费者,Thread,生产者,getName,System,println,public,模拟,out
From: https://www.cnblogs.com/damour-damocles/p/18606976

相关文章

  • uniapp精仿支付宝UI界面,首页/理财/消息/生活/口碑/我的,还有模拟支付宝扫码支付/收付款
    uniapp精仿支付宝UI界面,首页/理财/消息/生活/口碑/我的,还有模拟支付宝扫码支付/收付款等功能,界面漂亮颜值高,视频商城小工具等,蚂蚁森林种树养鸡农场偷菜样样齐用于视频,商城,直播,聊天等sumer-alipay介绍uniapp精仿支付宝UI界面,首页/理财/消息/生活/口碑/我的,还有模拟支付宝......
  • 初学rabbitMQ中的生产者和消费者(JavaSE环境下)
    生产者:publicstaticvoidmain(String[]args)throwsIOException,TimeoutException{//1创建一个连接工厂ConnectionFactoryConnectionFactoryconnectionFactory=newConnectionFactory();//2设置rabbitMQ的ip地址connectio......
  • 三菱FX3U模拟量产品的介绍
    FX3u可编程控制器模拟量产品包括:特殊适配器、特殊功能模块的连接1、连接在FX3U可编程控制器的左侧。2、连接特殊适配器时,需要功能扩展板。3、最多可以连接4台模拟量特殊适配器。4、使用高速输入输出特殊适配器时,请将模拟量特殊适配器连接在高速输入输出特殊适配器的后面。......
  • 【Linux】:多线程(POSIX 信号量 、基于环形队列的生产消费者模型)
    ......
  • 深入计算机语言之C++:STL之list的模拟实现
    ......
  • Java模拟Oracle函数MONTHS_BETWEEN注意事项
    Java模拟Oracle函数MONTHS_BETWEEN注意事项MONTHS_BETWEEN(DATE1,DATE2)用来计算两个日期的月份差。最近接到一个迁移需求,把OracleSQL接口迁移到新平台上,但新平台是采用Java计算的方式,所以我需求把SQL逻辑转成Java语言。在遇到MONTHS_BETWEEN时,遇到一些奇怪的问题,在此记......
  • 云主机安装Redis,基于CodeArts模拟电商平台秒杀抢购
    本文分享自华为云社区《云主机安装Redis并模拟电商平台秒杀抢购场景》,作者:开发者空间小蜜蜂。1.1案例介绍Redis是一个高性能的key-value数据库。Redis支持各种不同方式的排序。与memcached一样,为了保证效率,数据都是缓存在内存中。区别的是Redis会周期性的把更新的数据写入磁盘......
  • RabbitMQ快速入门 - 生产者和消费者的简单实现
    引入依赖<dependency><groupId>com.rabbitmq</groupId><artifactId>amqp-client</artifactId><version>5.7.3</version></dependency>编写生产者代码        RabbitMQ默认的⽤于客户端连接的TCP端⼝号是5672,需要提前进⾏开放代码及其注解p......
  • .NET 模拟&编辑平滑曲线
    本文介绍不依赖贝塞尔曲线,如何绘制一条平滑曲线,用于解决无贝塞尔控制点的情况下绘制曲线、但数据点不在贝塞尔曲线的场景。在上一家公司我做过一个平滑曲线编辑工具,用于轮椅调整加减速曲线。基于几个用户可控制的点,生成一条平滑的曲线,控制点需要保持在曲线上。今天和小伙伴沟通,......
  • 12.12 CW 模拟赛 T3. 消除贫困
    思路朴素容易发现一个人资金变化是这样的:对于\(op=1\)的情况,会将其直接变成\(x\)对于\(op=2\)的情况,将其变成\(\max(x,当前值)\)直接用线段树暴力的维护即可巧妙容易发现\(op=2\)相当于一个大保底,我们先倒着处理出每个人到\(i\)位置至少有多少......