Извините, это потенциально может быть очень глупым вопросом, но... Я делаю симуляцию, посредством которой клиент входит в магазин и перемещается через это хранилище, а затем через некоторое время помещается в список массивов проверок (из которых существует множество списков, которые он может потенциально ввести, что определяется addCustomer). Я связал каждого клиента, и проблема, с которой я столкнулась, - это блокировка для этого метода addCustomer, вызывающая массивное отставание, которое приводит к сбою моделирования, если оно выполняется слишком долго. Есть более простые способы обойти это (например, ограничить клиентов или замедлить их с помощью сна), но мне было интересно, можно ли создать несколько блокировок для одного и того же метода, так что, если один клиент вводит метод под одним замком, другой может ввести под другим замком. Или это эффективно разрушило бы точку блокировки и допустило бы ошибки с компьютера, смешивающего клиентов в разное время? Вот соответствующий код, дайте мне знать, если я пропустил некоторые критические разделы.....
Вот этот метод.
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();
}
}
И вот соответствующая часть runnable.
public void run() {
try {
customer.addRandomShopTime();
while (customer.shopTime > 0) {
Thread.sleep(5);
customer.setShopTime();
}
CheckoutOperator checkoutOperator = checkoutFloor.weightedCheckoutDeterminator();
checkoutOperator.addCustomer(customer);
Мы ценим любые предложения! Извините, никогда не делал многопотоков, так что это все новое для меня.
Каждый из ваших клиентов создает экземпляр подкласса CustomerContainer, который получает свой собственный объект Lock. Подумайте о том, чтобы сделать один последний статический замок, который должен защищать ресурс, к которому вы хотите получить доступ одновременно, в вашем случае clientList.
Теперь у вас есть один замок для каждого экземпляра клиента, потому что каждый клиент создает подклассу CustomerContainer, и ваша блокировка не является статичной. Рассмотрим также синхронизированное ключевое слово, если вам действительно не нужны функции блокировки повторного входа. Наличие нескольких блокировок на ресурс отрицает точку блокировки.
Блокировка необходима, чтобы избежать одновременного доступа двух или нескольких потоков к costumerList
, поэтому не рекомендуется включать более одного потока в критический раздел...
Помимо дополнительной проблемы, причиной которой было бы, почему два замка решают исходную проблему? Будет ли отставание меньше? Похоже, что настоящая причина заключается в том, что все, что удаляет клиентов из списка, намного медленнее, чем должно быть.