首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

Java中使用锁的生产者/消费者线程示例

在Java中,使用锁的生产者/消费者线程示例是一种常见的多线程编程模式,用于解决生产者和消费者之间的数据同步和通信问题。下面是一个简单的示例:

代码语言:txt
复制
import java.util.LinkedList;
import java.util.Queue;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class ProducerConsumerExample {
    private static final int BUFFER_SIZE = 10;
    private static final Queue<Integer> buffer = new LinkedList<>();
    private static final Lock lock = new ReentrantLock();
    private static final Condition notFull = lock.newCondition();
    private static final Condition notEmpty = lock.newCondition();

    public static void main(String[] args) {
        Thread producerThread = new Thread(new Producer());
        Thread consumerThread = new Thread(new Consumer());

        producerThread.start();
        consumerThread.start();
    }

    static class Producer implements Runnable {
        @Override
        public void run() {
            try {
                while (true) {
                    lock.lock();
                    try {
                        while (buffer.size() == BUFFER_SIZE) {
                            notFull.await();
                        }
                        int item = produceItem();
                        buffer.offer(item);
                        System.out.println("Produced: " + item);
                        notEmpty.signalAll();
                    } finally {
                        lock.unlock();
                    }
                    Thread.sleep(1000);
                }
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        }

        private int produceItem() {
            // 生成一个随机数作为生产的物品
            return (int) (Math.random() * 100);
        }
    }

    static class Consumer implements Runnable {
        @Override
        public void run() {
            try {
                while (true) {
                    lock.lock();
                    try {
                        while (buffer.isEmpty()) {
                            notEmpty.await();
                        }
                        int item = buffer.poll();
                        System.out.println("Consumed: " + item);
                        notFull.signalAll();
                    } finally {
                        lock.unlock();
                    }
                    Thread.sleep(1000);
                }
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        }
    }
}

这个示例中,使用了一个有界队列作为缓冲区,生产者线程负责生成物品并将其放入缓冲区,消费者线程负责从缓冲区中取出物品进行消费。为了保证线程安全和数据同步,使用了ReentrantLock作为锁,并通过Condition对象实现了生产者和消费者之间的等待和唤醒机制。

该示例中的生产者线程在缓冲区已满时等待,直到缓冲区有空闲位置才继续生产物品;消费者线程在缓冲区为空时等待,直到缓冲区有物品可供消费才继续消费。通过使用锁和条件变量,生产者和消费者之间实现了有效的线程通信和同步。

这种生产者/消费者模式在实际应用中非常常见,例如消息队列、线程池等场景都可以使用该模式来实现任务的生产和消费。在云计算领域,生产者/消费者模式可以用于异步任务处理、消息队列服务等场景。

腾讯云提供了一系列与云计算相关的产品和服务,例如云服务器、云数据库、云存储、人工智能等。具体推荐的产品和产品介绍链接地址可以根据实际需求和场景进行选择。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

高并发编程-线程生产者消费者的综合示例

需求 需求: 假设有10个线程,最多同时运行5个 要求: 不使用线程池,使用synchronized-wait¬ifyAll机制 ---- 实现 详见注释 package com.artisan.test...; import java.time.LocalTime; import java.util.*; /** * 需求: 假设有10个线程,最多同时运行5个 * 要求: 不使用线程池,使用synchronized-wait...while // 当集合中运行的线程数量大于5时,wait,放弃锁,不执行 while (CONTROLLIST.size() >= MAX_THREADS...不能在上一步的地方join , 这样的话就只能一个线程 一个线程的执行了(join会阻塞当前线程) 10个线程全部完成后,打印DONE 完成主要部分的编码后,就需要关注thread具体的业务逻辑了...: 定义一个锁 LinkedList ,当线程获取到锁,就将Control添加到Monitor中,如果大于规定的线程数,则wait 业务部分并行执行,当一个线程完成后,获取锁,从Monitor中移除一个

21110
  • Java线程(三):线程协作-生产者消费者问题

    上一篇讲述了线程的互斥(同步),但是在很多情况下,仅仅同步是不够的,还需要线程与线程协作(通信),生产者/消费者问题是一个经典的线程同步以及通信的案例。...该问题描述了两个共享固定大小缓冲区的线程,即所谓的“生产者”和“消费者”在实际运行时会发生的问题。生产者的主要作用是生成一定量的数据放到缓冲区中,然后重复此过程。...要解决该问题,就必须让生产者在缓冲区满时休眠(要么干脆就放弃数据),等到下次消费者消耗缓冲区中的数据的时候,生产者才能被唤醒,开始往缓冲区添加数据。...出现死锁时,两个线程都会陷入休眠,等待对方唤醒自己。该问题也能被推广到多个生产者和消费者的情形。...而不是if,在wait方法说明中,也推荐使用while,因为在某些特定的情况下,线程有可能被假唤醒,使用while会循环检测更稳妥。

    77300

    多线程中的生产者消费者问题 - 线程的同步

    同步问题的提出 操作系统中的生产者消费者问题,就是一个经典的同步问题。举一个例子,有两个人,一个人在刷盘子,另一个人在烘干。...这个示例要说明的问题是,生产者生产一个产品后就放入共享对象中,而不管共享对象中是否有产品。消费者从共享对象中取用产品,但不检测是否已经取过。...若共享对象中只能存放一个数据,可能出现以下问题(线程不同步的情况下): 生产者比消费者快时,消费者会漏掉一些数据没有取到。 消费者比生产者快时,消费者取相同的数据。...解决方法 为了解决线程运行速度问题,Java提供了一种建立在对象实例之上的交互方法。Java中的每个对象实例都有两个线程队列和他相连。第一个用来排列等待锁定标志的线程。...使用这个机制,程序能够非常简单的协调洗刷线程和烘干线程,而且并不需要了解这些线程的身份。

    51820

    java多线程-消费者和生产者模式

    /* * 多线程-消费者和生产者模式 * 在实现消费者生产者模式的时候必须要具备两个前提,一是,必须访问的是一个共享资源,二是必须要有线程锁,且锁的是同一个对象 * */ 1 /*资源类中定义了...name(名字):用来区分消费者还是生产者 2 * 定义了flag标记:用来区分有没有货物(默认生产一个就要消费一个) 3 * 定义了count(生产的个数统计)...68 TestSource ts=new TestSource(); 69 //创建生产者和消费者两个对象,并传入两者共同操作的唯一资源 70 Customer...版本以后,用lock和unlick代替了synchronized关键字 * 用await()代替了wait()方法 * 用signal()代替了notify() * 这里的signal可以指定唤醒莫一类的线程...System.out.println("生产"+name+"++"); 24 flag=true; 25 //notifyAll(); 26 //唤醒消费者线程

    81620

    Java多线程08——生产者消费者模式

    1 概念介绍 多线程环境下,我们经常需要多个线程的并发和相互通信。其中,有一个重要的多线程并发协作模型,即“生产者/消费者模式”。...2 角色介绍 生产者 负责生产数据的模块,可以是方法、对象、线程或进程。 消费者 负责处理数据的模块,可以是方法、对象、线程或进程。...缓冲区 消费者不能直接使用生产者的数据,在生产者和消费者之间有一个“缓冲区”。生产者将生产好的数据和内容放入“缓冲区”,消费者从“缓冲区”中取走要处理的数据。...缓冲区是实现并发的核心,设置缓冲区的优点: 实现线程的并发协作 设置缓冲区后,生产者线程只需要向缓冲区里面放入数据,而不需要去查看消费者消费的情况;同样,消费者只需要从缓冲区取走要处理的数据即可,也不需要查看生产者生产的情况...这样,就从逻辑上实现了“生产者线程”和“消费者线程”的分离,解除了生产者与消费者之间的耦合。

    21820

    Java学习笔记之多线程 生产者 消费者

    0x00 概述 本文涉及Java知识点有多线程,生产者,消费者。...3.1 生产者和消费者模式概述 概述     生产者消费者模式是一个十分经典的多线程协作模式,弄懂生产者消费者问题能够让我们对多线程编程的理解更加深刻     所谓生产者消费者问题,实际上主要是包含了两类线程...:       生产者线程用于生产数据       消费者线程用于消费数据     为了解耦生产者和消费者的关系,通常会采用共享的数据区域,就像一个仓库     生产者生产数据之后直接放置在共享数据区,...并不需要关系消费者的行为     消费者只需要从共享数据区获取数据,并不需要关心生产者的行为 Object类的等待和唤醒方法 3.2 生产者和消费者案例 需求:   生产者消费者案例中包含的类:...创建消费者和生产者对象,把奶箱对象作为构造方法参数传递,因为在这个类中要调用存储牛奶的操作     3. 对象,把奶箱对象作为构造方法参数传递,因为在这个类中要调用获取牛奶的操作     4.

    58110

    Java 多线程详解(四)------生产者和消费者

    /developer/article/1012630   通过前面三篇博客的介绍,基本上对Java的多线程有了一定的了解了,然后这篇博客根据生产者和消费者的模型来介绍Java多线程的一些其他知识。   ...解决办法:生产者生产一次数据了,就暂停生产者线程,等待消费者消费;消费者消费完了,消费者线程暂停,等待生产者生产数据,这样来进行。...() 方法来进行通信,流程如下: ①、当线程 A 执行 X 对象的同步方法时,A 线程持有 X 对象的 锁,B线程在 X 对象的锁池中等待 ②、A线程在同步方法中执行 X.wait() 方法时,A线程释放...X 对象的锁,进入 X 对象的等待池中 ③、在 X 对象的锁池中等待锁的 B 线程获得 X 对象的锁,执行 X 的另一个同步方法 ④、B 线程在同步方法中执行 X.notify() 方法,JVM 把...(这两个方法都已经过时了,不建议使用): suspend():使正在运行的线程放弃 CPU,暂停运行(不释放锁) resume():使暂停的线程恢复运行 情景:A 线程获得对象锁,正在执行一个同步方法,

    84650

    Java并发-定义锁以及消费者-生产者模式实现

    一、引子  对于Java并发的锁结构,我们常常使用的是synchonized结构,而由于其灵活度较低,所以在Java-5后提出了Lock接口,以及AbstractQueuedSynchronizer抽象类供我们方便且安全地来实现自定义锁结构...----  本文就两个实现方式来阐述“生产者-消费者模式”背景下的锁应用,第一种方式是使用Lock接口的自定义实现类来实现,第二种方式是使用synchronized关键字来实现。...并且以生产者和消费者的角度来验证此锁是否成功编写。...先看看其余接口以及类在锁构造过程中所起到的作用: Lock接口:锁是面向使用者的,它定义了使用者与锁交互的接口(比如可以允许两个线程并行访问),隐藏了实现细节; AQS抽象类:同步器面向的是锁的实现者...而AQS中涉及线程排队、休眠、唤醒等操作代码我们并不需要实现,我们所需做的就是关于线程获得到资源/释放资源时,修改同步器的状态,而这个状态将决定线程是否被唤醒,是否将尝试抢夺资源的锁放入等待队列并休眠。

    58210

    linux网络编程之posix 线程(四):posix 条件变量与互斥锁 示例生产者--消费者问题

    在pthread库中通过条件变量(Condition Variable)来阻塞等待一个条件,或者唤醒等待这个条件的线程。...注:在多处理器系统中,pthread_cond_signal 可能会唤醒多个等待条件的线程,这也是一种spurious wakeup。...当生产者线程较多,即生产得比较快,在这边假设是无界的缓冲区(比如链表),可以不停地生产,使用pthread_cond_signal  发出通知的时候,如果此时没有消费者线程在等待条件,那么这个通知将被丢弃...,等待结束的条件就是nready > 0;上面也说过当生产得比较快(生产者线程多)的时候,也有可能消费者线程一直不存在等待的状态,因为nready 的值很大,即产品资源很多。...现在设置的是2个消费者线程和1个生产者线程,所以动态输出来看一般是2个消费者线程轮流等待。 参考: 《linux c 编程一站式学习》 《UNP》

    1.4K00

    由生产者消费者问题看JAVA多线程

    我们可以认为所有的对象默认都具有一个锁,虽然我们看不到,也没有办法直接操作,但它是存在的。...wait()方法表示:当缓冲区已满或空时,生产者或消费者线程停止自己的执行,放弃锁,使自己处于等待状态,让另一个线程开始执行; notify()方法表示:当生产者或消费者对缓冲区放入或取出一个产品时...} 由生产者/消费者问题看JAVA多线程 } 由生产者/消费者问题看JAVA多线程 } 由生产者/消费者问题看JAVA多线程 由生产者/消费者问题看JAVA多线程} 你发现这个例子中的问题了吗...run()中的 synchronized其实并没有起什么作用。 对于BlockingQueue大家可以放心使用,这可不是它的问题,只是在它和别的对象之间的同步有问题。...管道方法PipedInputStream/PipedOutputStream 这个类位于java.io包中,是解决同步问题的最简单的办法,一个线程将数据写入管道,另一个线程从管道读取数据,这样便构成了一种生产者

    57030

    Java多线程之并发协作生产者消费者设计模式

    两个线程一个生产者个一个消费者 需求情景 两个线程,一个负责生产,一个负责消费,生产者生产一个,消费者消费一个 涉及问题 同步问题:如何保证同一资源被多个线程并发访问时的完整性。...wait()方法:当缓冲区已满/空时,生产者/消费者线程停止自己的执行,放弃锁,使自己处于等等状态,让其他线程执行。...notify()方法:当生产者/消费者向缓冲区放入/取出一个产品时,向其他等待的线程发出可执行的通知,同时放弃锁,使自己处于等待状态。...,向其他等待的所有线程发出可执行的通知,同时放弃锁,使自己处于等待状态。...也就是每次wait()后再notify()时先再次判断标记 代码改进(Resource中的if->while) Resource.java /** * Created by yuandl on 2016

    92620

    Java多线程编程(四)- 阻塞队列,生产者消费者模型,线程池

    , 继续出队列也会阻塞, 直到有其他线程往队列中插入元素  阻塞队列最主要的应用场景--->生产者消费者模型 2.生产者消费者模型的优点: 解耦合: 两个线程或者两个服务器之间如果直接访问,那么他们的耦合度就会很高...,导致产生的慢,队列可能为空阻塞,导致生产一个消费一个 4.标准库中的阻塞队列:  在 Java 标准库中内置了阻塞队列....里面有大量的线程可以直接给我们使用,不用系统去创建让我们高效的创建销毁线程,就和常量池类似,在Java程序构建时候准备好,等程序运行时直接加载到内存中使用  2.为什么要有线程池?...:工作队列(阻塞队列)(线程池的本质也是,生产者消费者模型,调用submit就是在生产任务,线程池则消费任务,线程池相当于消费者)  threadFactory: 工厂模式(工厂模式也属于一种设计模式)...newSingleThreadExecutor: 创建只包含单个线程的线程池 6.自己实现线程池: 线程池相当于消费者,消费阻塞队列里的任务,线程池的实现也是基于生产者消费者模型的:  package

    22410

    linux网络编程之posix 线程(三):posix 匿名信号量与互斥锁 示例生产者--消费者问题

    二、互斥锁 对于多线程的程序,访问冲突的问题是很普遍的,解决的办法是引入互斥锁(Mutex,MutualExclusive Lock),获得锁的线程可以完成“读-修改-写”的操作,然后释放锁给其它线程,...三、生产者消费者问题 生产者消费者问题概念参见这里。...,程序逻辑没太大变化,只是用pthread_mutex_lock 替代了 sem_mutex,其次这里是演示线程间同步,现在上述程序生产者消费者各一个线程,但生产者睡眠时间是消费者的5倍,故消费者会经常阻塞在...sem_wait(&g_sem_empty) 上面,因为缓冲区经常为空,可以将PRODUCTORS_COUNT 改成5,即有5个生产者线程和1个消费者线程,而且生产者睡眠时间还是消费者的5倍,从动态输出可以看出...,基本上就动态平衡了,即5个生产者一下子生产了5份东西,消费者1s消费1份,刚好在生产者继续生产前消费完。

    1.6K00

    通过实现生产者、消费者案例再次实践Java 多线程

    生产者、消费者案例 案例分析 在案例中明,蔬菜基地作为生产者,负责生产蔬菜,并向超市输送生产的蔬菜;消费者通过向超市购买获得蔬菜;超市怎作为生产者和消费者之间的共享资源,都会和超市有联系;蔬菜基地、共享资源...低(松)耦合:引入一个中间对象(共享资源)来,将生产者、消费者中需要对外输出或者从外数据的操作封装到中间对象中,这样,消费者和生产者将会持有这个中间对象的引用,屏蔽了生产者和消费者直接的数据交互....详情可查看我的另外一篇关于多线程的文章:Java 线程不安全分析,同步锁和Lock机制,哪个解决方案更好 在同步代码块中的同步锁必须选择多个线程共同的资源对象,当前生产者线程在生产数据的时候(先拥有同步锁...),其他线程就在锁池中等待获取锁;当生产者线程执行完同步代码块的时候,就会释放同步锁,其他线程开始抢锁的使用权,抢到后就会拥有该同步锁,执行完成后释放,其他线程再开始抢锁的使用权,依次往复执行。...因为没有同步锁,所以Lock机制中的线程通信就不能调用wait和notify方法了;同样的,Java 5 中也提供了解决方案,因此从Java5开始,可以: 使用Lock机制取代synchronized

    98600

    通过实现生产者、消费者案例再次实践Java 多线程

    线程通信 生产者、消费者案例 案例分析 在案例中,蔬菜基地作为生产者,负责生产蔬菜,并向超市输送生产的蔬菜;消费者通过向超市购买获得蔬菜;超市怎作为生产者和消费者之间的共享资源,都会和超市有联系; 蔬菜基地...低(松)耦合:引入一个中间对象(共享资源)来,将生产者、消费者中需要对外输出或者从外数据的操作封装到中间对象中,这样,消费者和生产者将会持有这个中间对象的引用,屏蔽了生产者和消费者直接的数据交互....详情可查看我的另外一篇关于多线程的文章:「JAVA」Java 线程不安全分析,同步锁和Lock机制,哪个解决方案更好 在同步代码块中的同步锁必须选择多个线程共同的资源对象,当前生产者线程在生产数据的时候...(先拥有同步锁),其他线程就在锁池中等待获取锁; 当生产者线程执行完同步代码块的时候,就会释放同步锁,其他线程开始抢锁的使用权,抢到后就会拥有该同步锁,执行完成后释放,其他线程再开始抢锁的使用权,依次往复执行...因为没有同步锁,所以Lock机制中的线程通信就不能调用wait和notify方法了;同样的,Java 5 中也提供了解决方案,因此从Java5开始,可以: 使用Lock机制取代synchronized

    48250

    使用BlockingQueue的生产者消费者模式

    BlockingQueue很好的解决了多线程中,如何高效安全“传输”数据的问题。通过这些高效并且线程安全的队列类,为我们快速搭建高质量的多线程程序带来极大的便利。使用场景。...通过一个共享的队列,可以使得数据由队列的一端输入,从另外一端输出;在生产者消费者模式中,通过队列的方式可以很方便的实现两者之间的数据共享。...强大的BlockingQueue使我们不用关心什么时候需要阻塞线程,什么时候需要唤醒线程。...put(anObject)把anObject加到BlockingQueue中,如果BlockQueue没有空间,则调用此方法的线程被阻断,直到BlockingQueue里面有空间再继续。...BlockingQueue获取所有可用的数据对象(还可以指定获取数据的个数),      通过该方法,可以提升获取数据效率;不需要多次分批加锁或释放锁。

    1.3K30
    领券