Серверный JavaScript 1.4. Руководство по использованию




Исключение Мёртвой Блокировки/Deadlock - часть 2


   if (...код определения неизвестного потребителя...) {

      // Создать нового потребителя.

      // Этот внутренний замок может вызвать проблемы!

      if ( project.customersLock.lock() ) {

          var id = project.customers.ID;
         id = id + 1;

         project.customers.ID = id;

          project.customersLock.unlock();
      }
   }

   project.ordersLock.unlock();
}

Заметьте, что каждый из этих фрагментов кода пытается получить второй замок, уже получив один. Это может вызвать проблемы. Предположим, что один поток начинает создание нового потребителя; он получает замок customersLock. В это же самое время другой поток начинает создание нового заказа; он получает замок ordersLock. Теперь первый поток запрашивает замок ordersLock. Поскольку второй поток уже получил этот замок, первый поток должен ждать. Предположим, однако, что второй поток теперь запрашивает замок customersLock. Первый поток уже имеет этот замок, поэтому второй поток должен ждать. Теперь потоки ждут друг друга. Поскольку никто их них не специфицировал таймаут, оба они будут ждать бесконечно.

В данном случае проблему можно легко устранить. Поскольку значения ID потребителя и номер заказа не зависят один от другого, нет никакого смысла вкладывать замки друг в друга. Вы можете избежать возможных тупиков, переписав оба фрагмента кода. Перепишите первый фрагмент так:

// Создать нового потребителя.


if ( project.customersLock.lock() ) {

   var id = project.customers.ID;

   id = id + 1;
   project.customers.ID = id;

   project.customersLock.unlock();
}

// Стартовать новый заказ для этого нового потребителя.




Содержание  Назад  Вперед