Что означает Lock, выпущенный во время ожидания: в дампе потока Java?

В этом дампе потока:

INFO   | jvm 3    | 2011/06/08 13:36:12 | "ExecuteThread: '38' for queue: 'default'" id=55 idx=0x78 tid=5316 prio=5 alive, in native, waiting, daemon
INFO   | jvm 3    | 2011/06/08 13:36:12 |     -- Waiting for notification on: weblogic/ejb20/locks/ExclusiveLockManager$LockWaiter@0x25EF8828[fat lock]
INFO   | jvm 3    | 2011/06/08 13:36:12 |     at jrockit/vm/Threads.waitForSignal(J)Z(Native Method)
INFO   | jvm 3    | 2011/06/08 13:36:12 |     at java/lang/Object.wait(J)V(Native Method)[optimized]
INFO   | jvm 3    | 2011/06/08 13:36:12 |     at weblogic/ejb20/locks/ExclusiveLockManager$LockBucket.lock(Ljava/lang/Object;Ljava/lang/Object;I)Z(ExclusiveLockManager.java:504)[optimized]
INFO   | jvm 3    | 2011/06/08 13:36:12 |     ^-- Lock released while waiting: weblogic/ejb20/locks/ExclusiveLockManager$LockWaiter@0x25EF8828[fat lock]
INFO   | jvm 3    | 2011/06/08 13:36:12 |     at weblogic/ejb20/locks/ExclusiveLockManager.lock(Ljava/lang/Object;Ljava/lang/Object;I)Z(ExclusiveLockManager.java:261)[optimized]
INFO   | jvm 3    | 2011/06/08 13:36:12 |     at weblogic/ejb20/manager/ExclusiveEntityManager.acquireLock(Ljava/lang/Object;Ljavax/transaction/Transaction;I)Z(ExclusiveEntityManager.java:210)[inlined]
INFO   | jvm 3    | 2011/06/08 13:36:12 |     at weblogic/ejb20/manager/ExclusiveEntityManager.getReadyBean(Ljava/lang/Object;Ljavax/transaction/Transaction;I)Ljavax/ejb/EntityBean;(ExclusiveEntityManager.java:267)[inlined]
INFO   | jvm 3    | 2011/06/08 13:36:12 |     at weblogic/ejb20/manager/ExclusiveEntityManager.preInvoke(Lweblogic/ejb20/internal/InvocationWrapper;)Ljavax/ejb/EnterpriseBean;(ExclusiveEntityManager.java:242)[optimized]
INFO   | jvm 3    | 2011/06/08 13:36:12 |     at weblogic/ejb20/internal/BaseEJBObject.preInvoke(Lweblogic/ejb20/internal/InvocationWrapper;Lweblogic/security/service/ContextHandler;)Lweblogic/ejb20/internal/InvocationWrapper;(BaseEJBObject.java:152)[inlined]
INFO   | jvm 3    | 2011/06/08 13:36:12 |     at weblogic/ejb20/internal/EntityEJBObject.preInvoke(Lweblogic/ejb20/internal/MethodDescriptor;Lweblogic/security/service/ContextHandler;)Lweblogic/ejb20/internal/InvocationWrapper;(EntityEJBObject.java:104)[inlined]
INFO   | jvm 3    | 2011/06/08 13:36:12 |     at foob/ejb/commodity/ejb_Commodity_etfd4i_EOImpl.getData()Lfoob/ejb/commodity/db/CommodityData;(ejb_Commodity_etfd4i_EOImpl.java:701)[optimized]
INFO   | jvm 3    | 2011/06/08 13:36:12 |     at foob/ejb/item/OurItem.loadCommodityData()V(OurItem.java:172)[optimized]
INFO   | jvm 3    | 2011/06/08 13:36:12 |     ^-- Holding lock: java/lang/Class@0x067EA070[fat lock]
INFO   | jvm 3    | 2011/06/08 13:36:12 |     at foob/ejb/item/OurItem.getCommodityData()Lfoob/ejb/commodity/db/CommodityData;(OurItem.java:251)
INFO   | jvm 3    | 2011/06/08 13:36:12 |     at foob/ejb/item/OurItem.getTheControlGid()Ljava/lang/String;(OurItem.java:259)
INFO   | jvm 3    | 2011/06/08 13:36:12 |     at foob/business/shipment/OurThing.getTheControlGid(Lfoob/util/jdbc/OurConnection;)Ljava/lang/String;(OurThing.java:379)

Что означает линия

Lock released while waiting: weblogic/ejb20/locks/ExclusiveLockManager$LockWaiter@0x25EF8828

иметь в виду? У нас было 8 других заблокированных потоков, ожидающих освобождения java/lang/Class@0x067EA070, которые удерживает этот поток, но я не понимаю, что этот поток блокировал, и что это означает, что блокировка была снята. Я бы подумал, что дамп потока - это событие типа остановки мира, и поэтому рассматриваемая строка не будет относиться к снятию блокировки во время дампа потока...

Кроме того, имеет ли какое-либо значение место его появления (т. е. линия над ним и под ним)?

Очевидно, я не ожидаю Java, поэтому я надеюсь, что это не слишком глупый вопрос. Спасибо за помощь!


person Joe Casadonte    schedule 15.06.2011    source источник
comment
Дамп потока — это событие типа остановки мира. Нет, это не так. Это просто дамп кадров стека всех потоков, выполняющихся в какой-либо точке JVM. Он может быть сгенерирован в момент события типа остановки мира, такого как сбой JVM. Изменить: вы можете получить дамп потока, отправив SIGBREAK процессу JVM.   -  person Vineet Reynolds    schedule 15.06.2011
comment
Vineet - под остановкой мира я имел в виду, что все выполнение в JVM приостанавливается, делается дамп потока, затем все выполнение возобновляется. Некоторые GC ведут себя так.   -  person Joe Casadonte    schedule 15.06.2011
comment
Хорошо, ты прав в этом смысле. Я интерпретировал это по-другому.   -  person Vineet Reynolds    schedule 15.06.2011
comment
Какая это версия WebLogic?   -  person Vineet Reynolds    schedule 15.06.2011
comment
@Vineet - я не уверен, думаю, 8.0.4 или 8.0.6.   -  person Joe Casadonte    schedule 15.06.2011


Ответы (3)


Из Руководства по инструментам Oracle JRockit JDK,

Семантика ожидания (уведомления) объекта в Java несколько сложна. Во-первых, чтобы войти в синхронизированный блок, вы должны заблокировать объект, а затем вызвать функцию wait() для этого объекта. В методе ожидания блокировка снимается до того, как поток переходит в спящий режим в ожидании уведомления. Когда поток получает уведомление, функция wait() повторно берет блокировку перед возвратом. Если поток взял блокировку и ожидает уведомления об этой блокировке, строка в трассировке стека, описывающая, когда блокировка была взята, не отображается как (Holding lock); это отображается как (Блокировка снята во время ожидания.)

Другими словами, это означает, что указанный поток имеет объект, который ранее получил блокировку, а затем в более поздний момент освободил ее, когда он вызвал object.wait(). Шаблон кода, похожий на поведение:

synchronized(lock) //acquires the lock
{
   ...
   do some work
   ...
   object.wait(); //releases the lock, and waits for a notification
}

Обновить

Если посмотреть на трассировку стека, окажется, что вы используете Entity EJB Beans, и, учитывая способ работы таких реализаций, блокировки обычно устанавливаются на Entity EJB. На самом деле это будет зависеть от стратегии параллелизма используется для управления одновременными транзакциями, которые должны обращаться к базе данных. Я подозреваю, что количество бобов либо слишком мало, либо есть только один компонент, который нужно зафиксировать.

person Vineet Reynolds    schedule 15.06.2011
comment
Это гораздо лучшая страница, чем та, которую я нашел: загрузить .oracle.com/docs/cd/E13188_01/jrockit/docs50/userguide/ -- спасибо! - person Joe Casadonte; 15.06.2011
comment
@Джо, взгляни на мое обновление. Это более конкретно для вашей трассировки стека. - person Vineet Reynolds; 15.06.2011

Найдите «Блокировка снята» на этой странице, и это дает довольно хорошее объяснение того, что происходит в рамках логики ожидания объекта.

http://download.oracle.com/docs/cd/E13188_01/jrockit/docs142/userguide/apstkdmp.html

Похоже, что это сообщение означает, что первоначальный вызов wait(), получивший notify(), перехватывает блокировку объекта.

Для справки в будущем, я нашел это, просто выполнив поиск в Google «Блокировка снята во время ожидания», и это была первая страница, которая появилась ... надеюсь, вы уже выполнили поиск в сети и просто не были удовлетворены тем, что вы нашел, и в этом случае мне жаль, если это не поможет.

person devyndraen    schedule 15.06.2011
comment
Да, я гуглил около получаса, прежде чем написать, но не нашел этого. Обычно у меня сумасшедшие навыки гугления, но сегодня они, должно быть, меня покинули — спасибо! - person Joe Casadonte; 15.06.2011

Скорее всего, это относится к записи двумя строками выше:

at java/lang/Object.wait(J)V(Native Method)[optimized]

wait() освободит текущую блокировку (блокировку, удерживаемую окружающим синхронизированным блоком) и дождется сигнала notify().

person pap    schedule 15.06.2011