简体   繁体   中英

Multiple locks for one method - Java

Sorry this could potentially be a really dumb question, but....I am making a simulation whereby a customer enters into a store, and moves through that store, and then after some time, is put into a checkout array list (of which there are numerous lists it could potentially enter, which is determined by addCustomer). I have threaded each customer and the problem I am having is the lock for this addCustomer method is causing a massive backlog which is crashing the simulation if it is run for too long. There are simpler ways around this (ie limit customers or slow them down with sleep) but I was wondering if it is possible to create multiple locks for the same method, so that if one customer is entering the method under one lock, another can enter under a different lock. Or would this effectively destroy the point of the lock and allow for errors with the computer mixing customers up at various times? Here is the relevant code, let me know if I have missed out on some critical sections.....

Here is the method.

public abstract class CustomerContainer {

    ArrayList<Customer> customerList = new ArrayList<Customer>();
    private Condition containerCondition;
    private Lock containerLock;
    int counter = 0;

    public CustomerContainer() {
        containerLock = new ReentrantLock();
        containerCondition = containerLock.newCondition();
    }

    public void addCustomer(Customer newCustomer) {
        containerLock.lock();
        try {
            customerList.add(newCustomer);
            System.out.println("no. of customers" + counter);
            counter++;
        } finally {
            containerLock.unlock();
        }
    }

And here is the relevant part of the runnable.

public void run() {
    try {
        customer.addRandomShopTime();
        while (customer.shopTime > 0) {
            Thread.sleep(5);
            customer.setShopTime();
        }
        CheckoutOperator checkoutOperator = checkoutFloor.weightedCheckoutDeterminator();
        checkoutOperator.addCustomer(customer);

Any suggestions would be appreciated! Sorry never done multi threading before so it is all new to me.

The lock is needed to avoid two or more threads accessing costumerList simultaneously, so it is not a good idea to allow more than one thread into the critical section...

Apart from the extra problem it would cause, why would two locks solve the original problem? Would the backlog be shorter? It seems that the real cause is that whatever removes customers from the list is much slower than it should be.

Each of your customers creates an instance of CustomerContainer subclass that receives its own Lock object. Consider making the one final static Lock which should protect the resource you wish to access concurrently, in your case customerList.

What you have now is one lock for each instance of customer because each customer creates CustomerContainer subclass and your lock is not static. Consider also keyword synchronized unless you really need reentrant lock features. Having more than one lock per resource negates the point of lock.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM