经典线程同步问题——生产者与消费者

题目描述

有一个缓冲区用于放产品,缓冲区容量有上限,假设最多可以放置10个产品。生产者生产产品并放在缓冲区,消费者从缓冲区拿走产品,如果缓冲区满了,生产者就必须等待,如果缓冲区空了,消费者就必须等待。

代码实现

缓冲区放置的产品数量使用java.util.concurrent.atomic包下的AtomicInteger来表示,保证增减操作的原子性,初始值为0。

生产方法首先判断缓冲区是否已满,若已满,就等待;同理,消费方法首先判断缓冲区是否为空,若为空,就等待。在生产或消费方法的结尾,都调用notifyAll()方法,唤醒正在等待的线程。

import java.util.concurrent.atomic.AtomicInteger;

public class ProduceAndConsume{

    static AtomicInteger NUM = new AtomicInteger(0);
    final static int MAX = 30;

    synchronized void produce(){
        int temp = NUM.get();
        if(temp == MAX){
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        try {
            Thread.sleep((int)(Math.random()*3000));  //模拟生产的时间
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("生产一个!");
        NUM.addAndGet(1);

        System.out.println("剩下"+NUM+"个");
        System.out.println();
        notifyAll();
    }

    synchronized void consume(){
        int temp = NUM.get();
        if(temp == 0){
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        try {
            Thread.sleep((int)(Math.random()*1000));  //模拟消费的时间
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("消费一个!");
        NUM.decrementAndGet();

        System.out.println("剩下"+NUM+"个");
        System.out.println();
        notifyAll();

    }

    public static void main(String[] args) {
        ProduceAndConsume produceAndConsume = new ProduceAndConsume();
        Thread thread1 = new Thread(new Producer(produceAndConsume));
        Thread thread2 = new Thread(new Consumer(produceAndConsume));
        thread1.start();
        thread2.start();
    }

}

生产者(实现Runnable接口):

public class Producer implements Runnable{

    final private ProduceAndConsume produceAndConsume;

    Producer(ProduceAndConsume produceAndConsume){
        this.produceAndConsume = produceAndConsume;
    }

    @Override
    public void run() {

        while (true){
            this.produceAndConsume.produce();
        }

    }
}

消费者(实现Runnable接口):

public class Consumer implements Runnable{

    final private ProduceAndConsume produceAndConsume;

    Consumer(ProduceAndConsume produceAndConsume){
        this.produceAndConsume = produceAndConsume;
    }

    @Override
    public void run() {

        while (true){
            this.produceAndConsume.consume();
        }
    }
}
# 多线程 

评论

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×