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

生产者消费者

时间:2022-11-01 22:11:28浏览次数:53  
标签:product String 生产者 lock name public Condition 消费者

一,线程通信问题

应用场景:生产者和消费者问题

假设仓库中只能存放一件产品,生产者将生产出来的产品放入仓库,消费者将仓库中产品取走消费

如果仓库中没有产品,则生产者将产品放入仓库,否则停止生产并等待,直到仓库中的产品被消费者取走为止

如果仓库中放有产品,则消费者可以将产品取走消费,否则停止消费并等待,直到仓库中再次放入产品为止

生产者:

package producerconsumer.demo1;

/**
 * @Author zl
 * @Description
 * @Date 2021/12/20 19:52
 */
public class Producer implements Runnable {

    private Product product;

    public Producer() {
    }

    public Producer(Product product) {
        this.product = product;
    }

    @Override
    public void run() {

        for (int i = 0; i < 10; i++) {
            synchronized (product) {
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                if (product.isFlag()) {
                    try {
                        product.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }

                if (i % 2 == 0) {
                    product.setBrand("哇哈哈");
                    product.setName("矿泉水");
                } else {
                    product.setBrand("旺仔");
                    product.setName("小馒头");
                }
                System.out.println("生产者生产了:" + product.getBrand() + "-" + product.getName());
                product.setFlag(true);

                product.notify();
            }
        }


    }
}

 

消费者:

package producerconsumer.demo1;

/**
 * @Author zl
 * @Description
 * @Date 2021/12/20 19:52
 */
public class Consumer implements Runnable {
    private Product product;

    public Consumer() {
    }

    public Consumer(Product product) {
        this.product = product;
    }

    @Override
    public void run() {

        for (int i = 0; i < 10; i++) {
            synchronized (product) {
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                if (!product.isFlag()) {
                    try {
                        product.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }

                System.out.println("消费者消费了:" + product.getBrand() + "-" + product.getName());
                product.setFlag(false);
                product.notify();
            }
        }


    }
}

 

产品:

package producerconsumer.demo1;

/**
 * @Author zl
 * @Description
 * @Date 2021/12/20 19:52
 */
public class Product {
    private String name;

    private String brand;

    private boolean flag = false;

    public boolean isFlag() {
        return flag;
    }

    public void setFlag(boolean flag) {
        this.flag = flag;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getBrand() {
        return brand;
    }

    public void setBrand(String brand) {
        this.brand = brand;
    }
}

 

测试:

package producerconsumer.demo1;

/**
 * @Author zl
 * @Description
 * @Date 2021/12/20 19:53
 */
public class Test {
    public static void main(String[] args) {
        Product product = new Product();
        Runnable t1 = new Producer(product);
        Runnable t2 = new Consumer(product);
        Thread producer = new Thread(t1);
        Thread consumer = new Thread(t2);
        producer.start();
        consumer.start();

    }
}

 二,Loc锁情况下的线程通信

Condition是在Java 1.5中才出现的,它用来替代传统的Object的wait()、notify()实现线程间的协作,相比使用Object的wait()、notify(),使用Condition的await()、signal()这种方式实现线程间协作更加安全和高效。 

 

它的更强大的地方在于:能够更加精细的控制多线程的休眠与唤醒。对于同一个锁,我们可以创建多个Condition,在不同的情况下使用不同的Condition 

一个Condition包含一个等待队列。一个Lock可以产生多个Condition,所以可以有多个等待队列。

在Object的监视器模型上,一个对象拥有一个同步队列和等待队列,而Lock(同步器)拥有一个同步队列和多个等待队列。 

Object中的wait(),notify(),notifyAll()方法是和"同步锁"(synchronized关键字)捆绑使用的;而Condition是需要与"互斥锁"/"共享锁"捆绑使用的。 

调用Condition的await()、signal()、signalAll()方法,都必须在lock保护之内,就是说必须在lock.lock()和lock.unlock之间才可以使用 

  • Conditon中的await()对应Object的wait();
    • Condition中的signal()对应Object的notify();
  • Condition中的signalAll()对应Object的notifyAll()。 
package thread.producerconsumer.demo4;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @Author zl
 * @Description
 * @Date 2021/12/20 19:52
 */
public class Product {
    private String name;

    private String brand;

    private Lock lock = new ReentrantLock();

    private Condition producerCondition = lock.newCondition();

    private Condition consumerCondition = lock.newCondition();

    private boolean flag = false;

    public boolean isFlag() {
        return flag;
    }

    public void setFlag(boolean flag) {
        this.flag = flag;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void set(String brand, String name) {
        lock.lock();
        try {
            if (isFlag()){
                producerCondition.await();
            }
            this.setBrand(brand);
            this.setName(name);
            System.out.println(Thread.currentThread().getName()+"生产者生产了:" + getBrand() + "-" + getName());
            flag=true;
            consumerCondition.signal();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }

    }

    public String getBrand() {
        return brand;
    }

    public void setBrand(String brand) {
        this.brand = brand;
    }

    public void get(){
        lock.lock();
        try {
            if (!isFlag()){
                consumerCondition.await();
            }

            System.out.println(Thread.currentThread().getName()+"消费者消费了:" + getBrand() + "-" + getName());
            flag=false;
            producerCondition.signal();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }
}

 

标签:product,String,生产者,lock,name,public,Condition,消费者
From: https://www.cnblogs.com/zhulei2/p/15725165.html

相关文章

  • kafka 从入门到精通2 、 创建kafka 生产者与消费者实例
    上一篇:​​kafka单机版和分布式版安装​​首先创建一个生产者:packageorg.training.hadoop.kafka;importorg.apache.kafka.clients.producer.KafkaProducer;importorg.a......
  • C# BlockingCollection(生产者/消费者)练习
    最近接手同事C#代码,(话说我一个C++程序员干嘛做这种事情,可能我是韭菜吧),为了能够承接,特地去拜读了《C#图解教程》,入门还是不错的。写代码嘛,异步编程肯定少不了,下面就是利用C......
  • Java生产者消费者问题-多线程-线程同步-线程安全-线程通信
    packageA_ShangGuiGu.Thread.ThreadTest;/***生产者消费者问题:生产者(Producer)将商品(commodity)交给商店(Shop),消费者(Consumer)进行消费*商店里的商品数量上限为20......
  • 生产者消费者问题
    生产者/消费者问题,也被称为有限缓冲问题。可以描述为:两个或者更多的线程共享同一个缓冲区,其中一个或多个线程作为“生产者“会不断的向缓冲区中添加数据,另一个或者多个线程......
  • 生产者消费者模式
    生产者消费者模式(Java实现)定义在⼀个⽣产环境中,⽣产者和消费者在同⼀时间段内共享同⼀块缓冲区,⽣产者负责向缓冲区添加数据,消费者负责从缓冲区取出数据使用资源类......
  • 2.RabbitMQ系列之生产者
    1.新建队列2.新增POM.xml配置文件<parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId......
  • RabbitMQ 生产者和消费代码实例
       启动服务   1.进入rabbitmq的安装sbin目录下cmd进入命令窗口          2.cmd输入命令rabbitmq-server.bat,如图启动成功    ......
  • 关于不同层次消费者的文化产品市场策略
    对于顶层社会,文化在于向奢侈化方向发展,使其具备标杆效应。纵观古今中外,撇开道德的褒贬,文化的极致都是在顶层社会沉淀,奢侈从来都是积极的推手。顶层社会的消费力意味着文化......
  • 多个生产者,单个消费者,信号量
    #include<stdio.h>#include<fcntl.h>#include<stdlib.h>#include<pthread.h>#include<semaphore.h>#definemin(a,b)((a)<(b)?(a):(b))#defineNBUFF10#de......
  • 消费者进行轮询等待
    #include<stdio.h>#include<stdlib.h>#include<pthread.h>#definemin(a,b)((a)<(b)?(a):(b))#defineMAXNITEMS1000000#defineMAXNTHREADS10intnitems......