消费前缓冲区充满

时间:2015-10-11 19:11:10

标签: java synchronization producer-consumer

import java.awt.List;
import java.util.ArrayList;
import java.util.Random;enter code here

public class shared {
private int [] buffer;
private int capacity;
Object lock;//=new Object();
int count=0;
int i,j;
//int i=0,j=0;

public shared(int capacity){
    this.capacity = capacity;
    buffer = new int[capacity];
     i=0;
     j=0;
     lock = new Object();
    //for(int k=0;k<capacity;k++){
        //buffer[k]=0;
    //}
}

public void producer() throws InterruptedException {
    //synchronized(lock){
    while(true){
        synchronized(lock){
    Random rn = new Random();
    int number = rn.nextInt(100);
    Thread.sleep(1000);

    while(count==capacity){
        try{
            System.out.println("BUffer is full");
        lock.wait();

        }catch(InterruptedException e){

        }

        //System.out.println("buffer is full");
    }
    System.out.println("producing" + number);
    buffer[i] = number;
    i = (i+1)%capacity;
    count++;
    lock.notifyAll();
}
    }
}


public void consumer(){
    //synchronized(lock){
    while(true){
        synchronized(lock){
    while(count==0){
        try{
            lock.wait();
        }catch(InterruptedException e){



        }
    }
        //int a = buffer.get(0);
        //buffer.remove(0);
        int consumed = buffer[j];
        System.out.println("consuming" + consumed);
        j=(j+1)%capacity;
        count--;
        lock.notifyAll();
        if((consumed%2)==0){
            System.out.println("the number displayed by the consumer is " + consumed);
            }
    }
    }
}
}

public class producer implements Runnable {
shared h;


public producer(shared s) {
    // TODO Auto-generated constructor stub
    h=s;
}

public void run(){
    //for(int i=0;i<10;i++){
    try {
        h.producer();
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

}

}
public class consumer implements Runnable {
shared h;

    public consumer(shared s) {
        // TODO Auto-generated constructor stub
        h=s;
    }
    public void run(){
        //for(int i=0;i<5;i++){
        h.consumer();

    }
    }
    public class implement {
    public static void main(String [] args) throws InterruptedException{
        shared s = new shared(10);
        Thread pro1 = new Thread(new producer(s));
        Thread con1 = new Thread(new consumer(s));
        pro1.start();
        con1.start();
        pro1.join();
        con1.join();
    }
    }

这是我写的整个代码。我得到的问题是我的缓冲区首先完全充满然后它被消耗掉了。我想让它随机消耗,即当第一个元素填满时,它可能会消耗掉或3-4个元素填满后。

1 个答案:

答案 0 :(得分:0)

我已经复制了你的实验并检查了事实上,生产者线程在消费者进入之前填充了缓冲区。这是因为只有当缓冲区已满时,生产者才会调用wait来给消费者机会。

多线程环境中的行为始终是随机的。当执行从生产者的同步块退出时,下一次迭代来得太快,以至于在其他线程有机会之前它再次进入块中。

如果你想以随机比例生产和消费,我建议你采取其他方式:

  • 首先,将sleep移出同步块。
  • 或者,总是将等待第一个 - 通知最后进入生产者循环,但在它们之间执行随机数量的插入。