1

the code at the bottom (1) was just for exercising but makes me curious why always the same Thread and only this Thread is able to receive the resource made by the producer. When I update the producer part with a Thread.sleep in my code like (2) all Threads get the resource randomly (I think). But why? Does the Sheduler works with LIFO? Or whats the "problem" here?

1

public class ProducerConsumer {
private static int resource = 0;
private static AtomicInteger id = new AtomicInteger();

public static void main(String... args) throws InterruptedException {
    final Object monitor = new Object();
    Runnable producer = () -> {
        try {
            while (!Thread.interrupted()) {
                // produce number
                println("producing ...");
                int number = (int) (Math.random() * 1000) + 1;
                Thread.sleep(number);
                println("produced " + number);

                // send number
                synchronized (monitor) {
                    resource = number;
                    println("notified");
                    monitor.notifyAll();
                }
            }
        } catch (InterruptedException e) {
            println("interrupted");
        }
    };
    Runnable consumer = () -> {
        final int innerId = id.getAndIncrement();
        try {
            while (!Thread.interrupted()) {
                // receive number
                int number;
                synchronized (monitor) {
                    while (resource == 0) {
                        println(innerId + " waiting ...");
                        monitor.wait();
                        println(innerId + " woke up ...");
                    }
                    number = resource;
                    resource = 0;
                }

                // consume number
                println("consumed " + number);
            }
        } catch (Exception e) {
            println("interrupted");
        }
    };

    new Thread(producer).start();
    new Thread(consumer).start();
    new Thread(consumer).start();
    new Thread(consumer).start();
    new Thread(consumer).start();
    Thread.sleep(10_000);
    Thread.currentThread().getThreadGroup().interrupt();

}

}

2

Runnable producer = () -> {
        try {
            while (!Thread.interrupted()) {
                // produce number
                println("producing ...");
                final int number = (int) (Math.random() * 1000) + 1;
                Thread.sleep(number);
                println("produced " + number);
                synchronized (monitor) {
                    setResource(number);
                    println("notified");
                    Thread.sleep(100);
                    monitor.notifyAll();
                }
            }
        } catch (InterruptedException e) {
            println("interrupted");
        }
    };

1 Answer 1

1

It is pseudo-random.

From the notifyAll doc:

The awakened threads will compete in the usual manner with any other threads that might be actively competing to synchronize on this object; for example, the awakened threads enjoy no reliable privilege or disadvantage in being the next thread to lock this object.

The implementation seems to fairly reliable (not random) in your case, but like the documentation says, it is not 100% reliable.

Sign up to request clarification or add additional context in comments.

3 Comments

i read this but when you run my code you'll see that actually always one specific Thread will get the resource which is far away from random.
Well, nothing in computing is totally random. The order in which a thread is chosen is in some way determined, but unpredictable for the user. It just happens to be the case, that with your specific code, the conditions always seem to be the same, so the same thread gets called every time.
@N-rG Once a thread successfully obtains a lock it is more likely to obtain a lock again. This is because while other threads will be asleep, a thread which just released a lock will be running and actively attempting to get the lock again.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.