commander spring
commander spring

Reputation: 51

Producer/Consumer thread example in Java using lock

public class ConsumerThreadExample {
public static void main(String[] args) throws InterruptedException {
    Consumer c = new Consumer();
    Thread a = new Thread(()->{while(true)c.consume();});
    Thread b = new Thread(()->{while(true)c.supply();});

    a.start();
    b.start();

    a.join();
    b.join();
    System.out.println("finish");
}
}

class Consumer{
private List<Integer> buffer = new ArrayList<>();
private Lock lock = new ReentrantLock();
private Condition notEnough = lock.newCondition();
private Condition toomuch = lock.newCondition();

public void consume(){
    lock.lock();
    try{
        while(buffer.isEmpty()){notEnough.await();
            System.out.println("consume waiting");}
        System.out.println(buffer);

        for(int i = 0; i < buffer.size(); i++){
            System.out.println("consume "+ buffer.remove(i));

            try {
                sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.println("signal supply");
        toomuch.signal();
    }
    catch (Exception e){}
    finally {
        lock.unlock();
    }
}

public void supply(){
    lock.lock();
    try{
        while(!buffer.isEmpty()){toomuch.await();
            System.out.println("supply waiting");}
        System.out.println("Adding");
        buffer.add(1);
        buffer.add(3);
        buffer.add(5);
        System.out.println(buffer);
        System.out.println("signal consume");
        notEnough.signal();
    }
    catch (Exception e){}
    finally {
        lock.unlock();
    }
}
}

Hello guys, consider the code above,I want to make a practice of classical thread example which is consumer/producer.So I expect the code to fill the buffer with supply(), then signal the consume() to consume the buffer.Whenever the buffer is empty, consume() signal the supply() again and so on.But the output seems a little bit weird. Output:

Adding
[1, 3, 5]
signal consume
consume waiting
[1, 3, 5]
consume 1
consume 5
signal supply
[3]
consume 3
signal supply
supply waiting
Adding
[1, 3, 5]
signal consume
consume waiting
[1, 3, 5]
consume 1
consume 5
signal supply
[3]
consume 3
signal supply
supply waiting
Adding
[1, 3, 5]

Why it consume 1 and 5 then signal supply()? Where is the 3? And Why it is not in the 1,3,5 order?

Upvotes: 0

Views: 115

Answers (1)

stribika
stribika

Reputation: 3176

Well in the first iteration

i = 0
buffer = [1, 3, 5]

And you remove 1. In the second iteration

i = 1
buffer = [3, 5]

And you remove 5. Then you exit the loop because i is now larger than the length.

Upvotes: 2

Related Questions