Java class as a monitor

I need to write a java program, but I need advice before starting on my own.

The program that I will write is to do the following:

  • Simulate a store that uses an advanced donut order

  • The store will not accept further orders, after ordering 5,000 donuts

Well, I’m kinda stuck in thinking if I have to write a java class to work as a Monitor or use the Java-Semaphore class instead?

Please advise me. Thanks for the help.

+3
source share
3 answers

Any java object can work as a monitor through the wait / notify methods inherited from Object:

Object monitor = new Object();

// thread 1    
synchronized(monitor) {
    monitor.wait();
}

// thread 2
synchronized(monitor) {
    monitor.notify();
}

( wait, , ). , .

, -. :

  • .
  • 5000, wait .
  • , notify , , .
  • .
  • , notify , .
  • 0, wait .

BlockingQueue,

+3

, ( ) . , 5000 - , , , .

synchronized :

class DonutShop {

    private int ordersTaken = 0;

    public synchronized int getOrdersTaken() {
        return ordersTaken;
    }

    public synchronized void increaseOrdersBy(int n) {
        ordersTaken += n;
    }

    // Other methods here
}

, ( , , , ). .

( , "set", "increment". "set" , shop.set(shop.get() + 1);, get set, . - - .


, , AtomicInteger, int, , DonutShop . , , , .

.

+1

Tudor, .

However, if you have a requirement that only x orders (x = 5000 for your case) can be processed at any given time, you can use the class java.util.concurrent.Semaphore. This is done specifically for use cases where you can only have a fixed number of tasks to perform - this is called permissions in terminologySemaphore

If you perform immediate processing, you can proceed with

private Semaphore semaphore = new Semaphore(5000);

public void process(Order order)
{
    if (semaphore.tryAcquire())
    {
        try
        {
            //do your processing here
        }
        finally
        {
            semaphore.release();
        }
    }
    else
    {
        throw new IllegalStateException("can't take more orders");
    }
}

If this takes more than this (requires human input, starting another thread / process, etc.), you need to add a callback to complete the processing, for example:

private Semaphore semaphore = new Semaphore(5000);

public void process(Order order)
{
    if (semaphore.tryAcquire())
    {
        //start a new job to process order
    }
    else
    {
        throw new IllegalStateException("can't take more orders");
    }
}

//call this from the job you started, once it is finished
public void processingFinished(Order order)
{
    semaphore.release();
    //any other post-processing for that order
}
0
source

All Articles