Java-生产消费者模式

 

方式一

package com.thread;

//生产消费者
class Sell {
    int product;

    public synchronized void produce() {
        if (product >= 10) { //产品>=10停止生产 等待消费者消费产品
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        } else {
            product++;
            System.out.println(Thread.currentThread().getName() + "生产了第" + product + "个产品!");
            notifyAll();//唤醒消费者
        }
    }

    public synchronized void consume() {
        if (product <= 0) {//产品<=0等待生产者生产产品
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        } else {
            System.out.println(Thread.currentThread().getName() + "消费了第" + product + "个产品!");
            product--;
            notifyAll();//唤醒生产者
        }
    }
}

//生产者
class Produce implements Runnable {
    Sell sell;

    public Produce(Sell sell) {
        this.sell = sell;
    }

    public void run() {
        System.out.println("生产者开始生产产品!");
        while (true) {
            try {
                Thread.sleep(150);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            sell.produce();
        }
    }

}
//消费者
class Consume implements Runnable {
    Sell sell;

    public Consume(Sell sell) {
        this.sell = sell;
    }

    public void run() {
        System.out.println("消费者开始消费产品!");
        while (true) {
            try {
                Thread.sleep(400);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            sell.consume();
        }
    }

}

public class TestProduceConsume {
    public static void main(String[] args) {
        Sell sell = new Sell();
        Produce produce = new Produce(sell);
        Consume consume = new Consume(sell);
        Thread p1 = new Thread(produce);
        Thread c1 = new Thread(consume);
        Thread c2 = new Thread(consume);
        p1.setName("生产者:");
        c1.setName("消费者1:");
        c2.setName("消费者2:");
        p1.start();
        c1.start();
        c2.start();
    }
}

方式二

package com.conncurrent;

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

//生产消费者
class Sell {
    int product;
    
    Lock lock;
    Condition notEmpy;
    Condition notFull;

    public Sell(Lock lock) {
        this.lock = lock;
        notEmpy = lock.newCondition();
        notFull = lock.newCondition();
    }

    public void produce() {
        try {
            lock.lock();
            if (product >= 10) { // 产品>=10停止生产 等待消费者消费产品
                try {
                    notEmpy.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            } else {
                product++;
                System.out.println(Thread.currentThread().getName() + "生产了第" + product + "个产品!");
                notFull.signalAll();// 唤醒消费者
            }
        } finally {
            lock.unlock();
        }
    }

    public void consume() {
        try {
            lock.lock();
            if (product <= 0) {// 产品<=0等待生产者生产产品
                try {
                    notFull.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            } else {
                System.out.println(Thread.currentThread().getName() + "消费了第" + product + "个产品!");
                product--;
                notEmpy.signalAll();// 唤醒生产者
            }
        } finally {
            lock.unlock();
        }
    }
}

//生产者
class Produce implements Runnable {
    Sell sell;

    public Produce(Sell sell) {
        this.sell = sell;
    }

    public void run() {
        System.out.println("生产者开始生产产品!");
        while (true) {
            try {
                TimeUnit.MILLISECONDS.sleep(150);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            sell.produce();
        }
    }

}

//消费者
class Consume implements Runnable {
    Sell sell;

    public Consume(Sell sell) {
        this.sell = sell;
    }

    public void run() {
        System.out.println("消费者开始消费产品!");
        while (true) {
            try {
                TimeUnit.MILLISECONDS.sleep(400);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            sell.consume();
        }
    }

}

public class TestProduceConsume {
    public static void main(String[] args) {
        Lock lock = new ReentrantLock();
        Sell sell = new Sell(lock);
        Produce produce = new Produce(sell);
        Consume consume = new Consume(sell);
        Thread p1 = new Thread(produce);
        Thread c1 = new Thread(consume);
        Thread c2 = new Thread(consume);
        p1.setName("生产者:");
        c1.setName("消费者1:");
        c2.setName("消费者2:");
        p1.start();
        c1.start();
        c2.start();
    }
}

方式三

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.TimeUnit;

public class ProducterConsumer {
    final static BlockingQueue<Apple> queue = new ArrayBlockingQueue<Apple>(20);

    public static void main(String[] args) {
        Produce produce = new Produce(queue);
        Consume consume = new Consume(queue);
        new Thread(produce).start();
        new Thread(consume).start();
    }
}

class Produce implements Runnable {
    BlockingQueue<Apple> queue;

    public Produce(BlockingQueue<Apple> queue) {
        this.queue = queue;
    }

    public void run() {
        int i = 0;
        while (true) {
            try {
                TimeUnit.MILLISECONDS.sleep(150);
                Apple apple = new Apple(++i);
                queue.put(apple);//生产产品 阻塞方法
                System.out.println("生产者开始生产产品:" + apple);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

}

class Consume implements Runnable {
    BlockingQueue<Apple> queue;

    public Consume(BlockingQueue<Apple> queue) {
        this.queue = queue;
    }

    public void run() {
        while (true) {
            try {
                TimeUnit.MILLISECONDS.sleep(400);
                Apple apple = queue.take();//获取产品 阻塞方法
                System.out.println("消费者开始消费产品:" + apple);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

}

class Apple {

    public Apple(int id) {
        super();
        this.id = id;
    }

    int id;

    @Override
    public String toString() {
        return "Apple [id=" + id + "]";
    }

}

 

总结

生产消费者模式 主要是对线程间通信的应用,方式一调用wait()方法让当前线程进入WAITING状态的同时释放CPU控制权,当生产者生产了产品或消费者消费了产品后调用notifyAll()方法,会唤醒WAITING状态的线程,这样就会一直生产消费下去。方式二和方式一原理相同,使用了java.util.concurrent包下的ReentrantLock类,该类提供了创建Condition实现类的方法,该实现类ConditionObject在AbstractQueuedSynchronizer(AQS)下实现,其中对应实现了await()方法(对应wait()),signalAll()方法(对应notifyAll()),推荐使用此方式。方式三使用的是阻塞队列,线程的调度交给队列的完成,实际内部也是使用的Condition来通信的。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值