首页 > 编程语言 > 详细

线程协作

时间:2021-04-25 18:01:09      阅读:28      评论:0      收藏:0      [点我收藏+]

线程协作

  • 生产者消费者

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

    • 假设仓库中只能存放一件产品 , 生产者将生产出来的产品放入仓库 , 消费者将仓库中产品取走消费 .
    • 如果仓库中没有产品 , 则生产者将产品放入仓库 , 否则停止生产并等待 , 直到仓库中的产品被消费者取走为止 .
    • 如果仓库中放有产品 , 则消费者可以将产品取走消费 , 否则停止消费并等待 ,直到仓库中再次放入产品为止。
  • 这是一个线程同步问题 , 生产者和消费者共享同一个资源 , 并且生产者和消费者之间相互依赖 , 互为条件.

    1. 对于生产者 , 没有生产产品之前 , 要通知消费者等待 . 而生产了产品之后 , 又需要马上通知消费者消费
    2. 对于消费者 , 在消费之后 , 要通知生产者已经结束消费 , 需要生产新的产品以供消费.
    3. 产者消费者问题中 , 仅有synchronized是不够的
    4. synchronized 可阻止并发更新同一个共享资源 , 实现了同步
    5. synchronized 不能用来实现不同线程之间的消息传递 (通信)
  • 解决方式

    • 管程法

      并发协作模型 “ 生产者 / 消费者模式 ” —->管程法

      生产者 : 负责生产数据的模块 (可能是方法 , 对象 , 线程 , 进程) ;

      消费者 : 负责处理数据的模块 (可能是方法 , 对象 , 线程 , 进程) ;

      缓冲区 : 消费者不能直接使用生产者的数据 , 他们之间有个 “ 缓冲区

      生产者将生产好的数据放入缓冲区 , 消费者从缓冲区拿出数据

//测试生产者消费者模型:管程法
public class Demo05 {
    public static void main(String[] args) {
        Syncontainer syContainer = new Syncontainer();
        new Productor(syContainer).start();
        new Consumer(syContainer).start();
    }
}
//生产者
class Productor extends Thread{
    Syncontainer syContainer;
    public Productor(Syncontainer syContainer) {
        this.syContainer = syContainer;
    }
    @Override
    public void run() {
        super.run();
        for (int i = 1; i < 100; i++) {
            syContainer.push(new Product(i));
            System.out.println("生产了--->" + i);
        }
    }
}
//消费者
class Consumer extends Thread{
    Syncontainer syContainer;
    public Consumer(Syncontainer syContainer){
        this.syContainer=syContainer;
    }
    @Override
    public void run() {
        super.run();
        for (int i = 1; i < 100; i++) {
            Product pop = syContainer.pop();
            System.out.println("消费了"+pop.count);
        }
    }
}
//产品
class Product {
    //数量
    int count;
    public Product(int id) {
        this.count = id;
    }
}
//缓冲区、
class Syncontainer{
    //需要一个容器
    Product[] products = new Product[10];
    //容器计数器
    int count = 0;
    //生产者放入产品
    public synchronized void push(Product product){
        //如果容器满了,需等待消费者消费
        if (count == products.length){
            //通知消费者消费,生产等待
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        } else {
            //如果容器没有满,需继续生产产品
            products[count] = product;
            count++;
            //通知消费者消费,唤醒消费者
            this.notifyAll();
        }
    }
    //消费者消费产品
    public synchronized Product pop() {
        if (count == 0) {
            //通知生产者生产,消费者等待
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        //可以消费
        count--;
        Product product = products[count];
        this.notifyAll();
        return product;
    }
}
  • 信号灯法:

//测试生产者消费者模型:信号灯法
public class Demo06 {
    public static void main(String[] args) {
        Product product = new Product();
        new Producer(product).start();
        new Consumer(product).start();
    }
}
//生产者
class Producer extends Thread {
    Product product;
    public Producer(Product product){
        this.product = product;
    }
    @Override
    public void run() {
        for (int i = 0; i < 20; i++) {
            if (i%2==0){
                try {
                    this.product.produce("电视");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
//消费者
class Consumer extends Thread{
    Product product;
    public Consumer(Product product){
        this.product = product;
    }
    @Override
    public void run() {
        for (int i = 0; i < 20; i++) {
            try {
                product.consume();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
//产品
class Product{
    String name;
    boolean flag = true;
    public synchronized void produce(String name) throws InterruptedException {
        if (!flag){
            this.wait(); //生产者等待
        }
        System.out.println("生产产品");
        //通知消费者消费
        this.notifyAll();//通知唤醒
        this.name = name;
        this.flag = !this.flag;
    }

    public synchronized void consume() throws InterruptedException {
        if (flag){
            this.wait();
        }
        System.out.println("正在消费"+name);
        //通知生产者生产
        this.notifyAll();
        this.flag = !this.flag;
    }
}

线程协作

原文:https://www.cnblogs.com/saxonsong/p/14700149.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!