2013-11-11 3 views
1

Я хочу, чтобы сервер выполнял определенную часть кода служебного импонента для одного клиента за раз, поточно-безопасный; и последовательно. Вот часть реализации службы на стороне сервера, которая делает это:GWT - блок синхронизации на стороне сервера

public BorcData getBorcData(String userId) throws GeneralException, EyeksGwtException 
{ 
     StoredProcedure sp = DALDB.storedProcedure("BORCBILDIRIM_GETMUKDATA_SP"); 
     DALResult spResult; 
     Row spRow; 
     String vergiNo; 
     String asamaOid; 

     synchronized (ServerUtility.lock_GeriArama_GetBorcData_GetMukDataSP) 
     { 
      String curOptime =CSDateUtility.getCurrentDateTimeToSave(); 

      sp.addParam(curOptime); 
      spResult = sp.execute(); 

      if (!spResult.hasNext()) 
      { 
       throw new GeneralException("53", ""); 
      } 
     } 

Вы видите синхронизированный блок. Объект, который я использую для замка определяется как:

public static Object lock_GeriArama_GetBorcData_GetMukDataSP = new Object(); 

Моей проблема: Я думаю, что я видел, что в то время как клиент ждет, чтобы выполнить этот синхронизированный блок в течение длительного времени, некоторые другие клиенты называют эту услугой и выполнил этот блок, не вставая и продолжая. Первый клиент все еще ждал.

Я знаю, что на стороне сервера работает чистая Java. Возможно ли, что серверная сторона несправедлива по отношению к клиентам и не запускает запрос самого длинного ожидающего клиента?

EDIT: Собственно; справедливость даже не является реальной проблемой. Иногда клиенты выглядят так, будто они просто зависают в этой синхронизированной части; ожидая вечно, чтобы служба закончилась.

ответ

3

Сначала ваш замок Объект всегда должен быть объявлен final. Это не устраняет никаких проблем, но это говорит вам, если вы сделали что-то неправильно (например, установили блокировку для другой блокировки).

Одним из способов обеспечения справедливости является использование ReentrantLock, инициализированного с помощью истинного (справедливого планирования). Это гарантирует, что клиенты не будут вешать бесконечно, но выполняются в порядке FIFO. Хорошая вещь заключается в том, что это требует лишь незначительных изменений в код, заменив все эти синхронизированные блоки:

lock.lock(); 
try { 
    // previous code 
} finally { 
    lock.unlock(); 
} 

наконец это просто мера безопасности, если какая-либо часть внутри сгенерирует исключение.

Кроме того, ваш код выглядит отлично, поэтому проблема, скорее всего, будет в БД и не вызвана использованием синхронизации вообще.

+0

Thanks; Я дам эту попытку и завтра буду здесь с результатом. В принципе, теперь кажется, что синхронизация ненадежна, так как клиентские запросы зависают без видимой причины. – Halo

+0

Synchronized является надежным, но он не гарантирует ничего, кроме того, что он сможет в любой момент включить только один поток. Если этого недостаточно (например, справедливое планирование в вашем случае), вам нужно использовать другую функцию блокировки. Неопределенная подвеска - это не ошибка синхронизации. – TwoThe

+0

До сих пор; ReentrantLock работает отлично; и никакой клиент, кажется, не висит перед замком. Спасибо за помощь – Halo

Смежные вопросы