行业资讯 2025年08月6日
0 收藏 0 点赞 925 浏览 2898 个字
摘要 :

文章目录 异步模式 传统版 改进版 阻塞队列 异步模式 传统版 异步模式之生产者/消费者: class ShareData { private int number = 0; private Lock lock = ne……




  • 异步模式
    • 传统版
    • 改进版
    • 阻塞队列

    异步模式

    传统版

    异步模式之生产者/消费者:

    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(number != 0) {
                    // 等待不能生产
                    condition.await();
                }
                // 干活
                number++;
                System.out.println(Thread.currentThread().getName() + "\\t " + number);
                // 通知 唤醒
                condition.signalAll();
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }
        }
    
        public void decrement() throws Exception{
            // 同步代码块,加锁
            lock.lock();
            try {
                // 判断 防止虚假唤醒
                while(number == 0) {
                    // 等待不能消费
                    condition.await();
                }
                // 干活
                number--;
                System.out.println(Thread.currentThread().getName() + "\\t " + number);
                // 通知 唤醒
                condition.signalAll();
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }
        }
    }
    
    public class TraditionalProducerConsumer {
        public static void main(String[] args) {
            ShareData shareData = new ShareData();
            // t1线程,生产
            new Thread(() -> {
                for (int i = 0; i < 5; i++) {
                    shareData.increment();
                }
            }, "t1").start();
    
            // t2线程,消费
            new Thread(() -> {
                for (int i = 0; i < 5; i++) {
                    shareData.decrement();
                }
            }, "t2").start(); 
        }
    }
    

    改进版

    异步模式之生产者/消费者:

    • 消费队列可以用来平衡生产和消费的线程资源,不需要产生结果和消费结果的线程一一对应
    • 生产者仅负责产生结果数据,不关心数据该如何处理,而消费者专心处理结果数据
    • 消息队列是有容量限制的,满时不会再加入数据,空时不会再消耗数据
    • JDK 中各种阻塞队列,采用的就是这种模式

    public class demo {
        public static void main(String[] args) {
            MessageQueue queue = new MessageQueue(2);
            for (int i = 0; i < 3; i++) {
                int id = i;
                new Thread(() -> {
                    queue.put(new Message(id,"值"+id));
                }, "生产者" + i).start();
            }
            
            new Thread(() -> {
                while (true) {
                    try {
                        Thread.sleep(1000);
                        Message message = queue.take();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            },"消费者").start();
        }
    }
    
    //消息队列类,Java间线程之间通信
    class MessageQueue {
        private LinkedList<Message> list = new LinkedList<>();//消息的队列集合
        private int capacity;//队列容量
        public MessageQueue(int capacity) {
            this.capacity = capacity;
        }
    
        //获取消息
        public Message take() {
            //检查队列是否为空
            synchronized (list) {
                while (list.isEmpty()) {
                    try {
                        sout(Thread.currentThread().getName() + ":队列为空,消费者线程等待");
                        list.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                //从队列的头部获取消息返回
                Message message = list.removeFirst();
                sout(Thread.currentThread().getName() + ":已消费消息--" + message);
                list.notifyAll();
                return message;
            }
        }
    
        //存入消息
        public void put(Message message) {
            synchronized (list) {
                //检查队列是否满
                while (list.size() == capacity) {
                    try {
                        sout(Thread.currentThread().getName()+":队列为已满,生产者线程等待");
                        list.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                //将消息加入队列尾部
                list.addLast(message);
                sout(Thread.currentThread().getName() + ":已生产消息--" + message);
                list.notifyAll();
            }
        }
    }
    
    final class Message {
        private int id;
        private Object value;
        //get set
    }
    

    阻塞队列

    public static void main(String[] args) {
        ExecutorService consumer = Executors.newFixedThreadPool(1);
        ExecutorService producer = Executors.newFixedThreadPool(1);
        BlockingQueue<Integer> queue = new SynchronousQueue<>();
        producer.submit(() -> {
            try {
                System.out.println("生产...");
                Thread.sleep(1000);
                queue.put(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        consumer.submit(() -> {
            try {
                System.out.println("等待消费...");
                Integer result = queue.take();
                System.out.println("结果为:" + result);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
    }
    

微信扫一扫

支付宝扫一扫

版权: 转载请注明出处:https://www.zuozi.net/10409.html

管理员

相关推荐
2025-08-06

文章目录 一、Reader 接口概述 1.1 什么是 Reader 接口? 1.2 Reader 与 InputStream 的区别 1.3 …

988
2025-08-06

文章目录 一、事件溯源 (一)核心概念 (二)Kafka与Golang的优势 (三)完整代码实现 二、命令…

465
2025-08-06

文章目录 一、证明GC期间执行native函数的线程仍在运行 二、native线程操作Java对象的影响及处理方…

348
2025-08-06

文章目录 一、事务基础概念 二、MyBatis事务管理机制 (一)JDBC原生事务管理(JdbcTransaction)…

456
2025-08-06

文章目录 一、SnowFlake算法核心原理 二、SnowFlake算法工作流程详解 三、SnowFlake算法的Java代码…

517
2025-08-06

文章目录 一、本地Jar包的加载操作 二、本地Class的加载方法 三、远程Jar包的加载方式 你知道Groo…

832
发表评论
暂无评论

还没有评论呢,快来抢沙发~

助力内容变现

将您的收入提升到一个新的水平

点击联系客服

在线时间:08:00-23:00

客服QQ

122325244

客服电话

400-888-8888

客服邮箱

122325244@qq.com

扫描二维码

关注微信客服号