java实现——线程协作和通信

生产者和消费者问题

生产者消费者问题(英语:Producer-consumer problem),也称有限缓冲问题(英语:Bounded-buffer problem),是一个多进程同步问题的经典案例。该问题描述了共享固定大小缓冲区的两个进程——即所谓的“生产者”和“消费者”——在实际运行时会发生的问题。生产者的主要作用是生成一定量的数据放到缓冲区中,然后重复此过程。与此同时,消费者也在缓冲区消耗这些数据。该问题的关键就是要保证生产者不会在缓冲区满时加入数据,消费者也不会在缓冲区中空时消耗数据。

1.1java提供的机制

均是Object类中的方法,都只能在同步方法和同步代码块中使用。

void notify() 唤醒一个在这个对象的监视器上等待的单个线程。
void notifyAll() 唤醒正在等待此对象监视器上的所有线程。
void wait() 使当前线程等待另一个线程调用此对象的方法或 notify() notifyAll()方法。
void wait(long timeout) 使当前线程等待另一个线程调用此对象的方法或 notify() notifyAll()方法,或一个指定的时间流逝。
void wait(long timeout, int nanos) 使当前线程等待另一个线程调用此对象的方法或 notify() notifyAll()方法,或者其他某个线程中断当前线程,或一定量的实际时间已经过去了。

1.2提供缓冲区

/**
 * 管程法解决生产者消费者问题
 */
public class TestBuffer {
    
    
    public static void main(String[] args) {
    
    
        //创建缓冲区
        BufferSynContainer container = new BufferSynContainer();
        new Producer(container).start();
        new Consumer(container).start();
    }
}

class Producer extends Thread{
    
    

    BufferSynContainer buffer;

    public Producer(BufferSynContainer buffer){
    
    
        this.buffer = buffer;
    }
    //生产
    public void run() {
    
    
        for (int i = 0; i < 100; i++) {
    
    
            buffer.push(new Chicken(i+1));
            System.out.println("生产了"+(i+1)+"只鸡");
        }
    }
}

class Consumer extends Thread{
    
    
    BufferSynContainer buffer;

    public Consumer(BufferSynContainer buffer){
    
    
        this.buffer = buffer;
    }

    //消费
    public void run() {
    
    
        for (int i = 0; i < 100; i++) {
    
    
            System.out.println("消费了-->"+buffer.pop().getId()+"只鸡");
        }
    }
}

//产品
class Chicken{
    
    
    private int id;

    public Chicken(int id) {
    
    
        this.id = id;
    }

    public int getId() {
    
    
        return id;
    }

    public void setId(int id) {
    
    
        this.id = id;
    }
}

class BufferSynContainer{
    
    
    //缓冲区大小
    Chicken[] chickens = new Chicken[10];
    int count = 0;

    //生产者生产
    public synchronized void push(Chicken chicken){
    
    
        //容器满了,生产者等待
        if (count==chickens.length){
    
    
            try {
    
    
                this.wait();
            } catch (InterruptedException e) {
    
    
                e.printStackTrace();
            }
        }
        //放入缓冲区
        chickens[count] = chicken;
        count++;
        //通知消费者可以消费了
        this.notifyAll();
    }

    //消费者消费产品
    public synchronized Chicken pop(){
    
    
        //看缓冲区中是否有数据
        if (count<=0){
    
    
            try {
    
    
                this.wait();//没有产品等待
            } catch (InterruptedException e) {
    
    
                e.printStackTrace();
            }
        }
        //如果有数据进行消费
        count--;
        Chicken chicken = chickens[count];

        //吃完了,通知生产者生产
        this.notifyAll();
        return chicken;
    }
}

1.3信号灯法——并发协作

semaphore mutex = 1;
 2 semaphore fillCount = 0;
 3 semaphore emptyCount = BUFFER_SIZE;
 4 
 5 procedure producer() {
    
    
 6     while (true) {
    
    
 7         item = produceItem();
 8         down(emptyCount);
 9             down(mutex);
10                 putItemIntoBuffer(item);
11             up(mutex);
12         up(fillCount);
13     }
14 }
15 procedure consumer() {
    
    
16     while (true) {
    
    
17         down(fillCount);
18             down(mutex);
19                 item = removeItemFromBuffer();
20             up(mutex);
21         up(emptyCount);
22         consumeItem(item);
23     }
24 }

猜你喜欢

转载自blog.csdn.net/joey_ro/article/details/109963542