2009-10-23 2 views
1

У меня есть служба REST, построенная с использованием Jersey.Сбрасывает ли этот свалка, что у меня есть тупик?

Когда я выполнил «завиток» против моего REST API, команда зависает.

Я запускал jstack & Это обобщенный результат двух потоков в состоянии BLOCKED.

"pool-2-thread-11" prio=6 tid=0x01d51800 nid=0x2394 
waiting for monitor entry [0x05e6f000..0x05e6fce8] 
java.lang.Thread.State: BLOCKED (on object monitor) 
    at com.moi.DefaultImageProcessor$DownloadAndScaleCallable.call(
      DefaultImageProcessor.java:168) 
    - waiting to lock <0x257aa440> 
    (com.moi.ImageUriMutexImpl$MutexImpl) 
     at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303) 
     at java.util.concurrent.FutureTask.run(FutureTask.java:138) 
     at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:441) 
     at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303) 
     at java.util.concurrent.FutureTask.run(FutureTask.java:138) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(
     ThreadPoolExecutor.java:885) 

"pool-2-thread-10" prio=6 tid=0x01d51000 nid=0x18d0 
waiting for monitor entry [0x05e1f000..0x05e1fd68] 
java.lang.Thread.State: BLOCKED (on object monitor) 
    at com.moi.DefaultImageProcessor$DownloadAndScaleCallable.call(
      DefaultImageProcessor.java:168) 
    - waiting to lock <0x257aa6b8> 
    (com.moi.ImageUriMutexImpl$MutexImpl) 
     at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303) 
     at java.util.concurrent.FutureTask.run(FutureTask.java:138) 
     at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:441) 
     at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303) 
     at java.util.concurrent.FutureTask.run(FutureTask.java:138) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(
     ThreadPoolExecutor.java:885) 

Я хочу знать, как читать этот сброс стека. Какие признаки следует искать в тупике?

ОБНОВЛЕНИЕ Я решил свою проблему! В основном я делаю HttpClient 4.0 GET внутри синхронизированного блока. HttpClient вел себя плохо & не возвращался & он держал на замках. Через jstack было несколько потоков, удерживающих блокировки, которые вызвали проблему выше. Теперь я понимаю, что это были не тупики, но мои синхронизированные блоки слишком долго возвращались.

+1

Они заблокированы в порядке ... – Bostone

ответ

5

От маленькой трассировки стека нитки ждут только для того, чтобы получить блокировку. В трассировке найдите объекты 0x257aa440 и 0x257aa6b8 и посмотрите, кто заблокировал эти объекты. Проверьте, заблокирован ли этот поток.

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

+1

«искать объект 0x257aa440»: вы имеете в виду «искать поток, который блокирует объект 0x257aa440»? (не троллинг, искренне требующий точности) –

1

Учитывая вы заметили, что команда «зависает», и вы определили две темы, заблокированную мьютекс ... Я бы сказал, что вы читаете знаки довольно хорошо ...

Это действительно зависит от того, что делает ваша служба. Ищите проблемы с производительностью и проблемы согласованности данных. Например, застревание и не реагирование, или даже серьезное поражение производительности по мере увеличения количества запросов - это хорошие признаки, которые могут возникнуть у вас. Кроме того, непоследовательные данные между несколькими запросами (опять же, в зависимости от вашей службы) также могут указывать на проблему.

0

Это два потока в конфликте за один и тот же ресурс, поэтому нет этого в себе, это не проблема. Однако это может быть половина проблемы.

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

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

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

1

A (обычный) тупик легко обнаружить с помощью jstack - он скажет, что есть тупик. (Могут быть случаи, когда, например, потоки ждут друг друга, но не друг от друга, блокировка - EventQueue.invokeAndWait часто вызывает это.)

Здесь у нас есть два потока блоков, пытающихся заблокировать разные объекты (с хешем идентификации коды 0x257aa440 и 0x257aa440).Вероятно, вы найдете другие потоки, которые действительно удерживают эти блокировки (просто используйте find в текстовом редакторе). Возможно, монитор был выпущен очень скоро и не удерживается. В этом случае вы, вероятно, видите сильно противоречивые блокировки.

2

Посмотрите на this question. Это выдержка из StackTrace, которые могут быть сгенерированы:

"Thread-1" prio=10 tid=0x0841ac00 nid=0x77d waiting for monitor entry [0xb42bf000] 
    java.lang.Thread.State: BLOCKED (on object monitor) 
    at Deadlock$Friend.bowBack(Deadlock.java:16) 
    - waiting to lock <0x8b80def8> (a Deadlock$Friend) 
    at Deadlock$Friend.bow(Deadlock.java:13) 
    - locked <0x8b80df08> (a Deadlock$Friend) 
    at Deadlock$2.run(Deadlock.java:28) 
    at java.lang.Thread.run(Thread.java:619) 

"Thread-0" prio=10 tid=0x08419400 nid=0x77c waiting for monitor entry [0xb4310000] 
    java.lang.Thread.State: BLOCKED (on object monitor) 
    at Deadlock$Friend.bowBack(Deadlock.java:16) 
    - waiting to lock <0x8b80df08> (a Deadlock$Friend) 
    at Deadlock$Friend.bow(Deadlock.java:13) 
    - locked <0x8b80def8> (a Deadlock$Friend) 
    at Deadlock$1.run(Deadlock.java:25) 
    at java.lang.Thread.run(Thread.java:619) 



Found one Java-level deadlock: 
============================= 
"Thread-1": 
    waiting to lock monitor 0x083f1464 (object 0x8b80def8, a Deadlock$Friend), 
    which is held by "Thread-0" 
"Thread-0": 
    waiting to lock monitor 0x083efc90 (object 0x8b80df08, a Deadlock$Friend), 
    which is held by "Thread-1" 

Java stack information for the threads listed above: 
=================================================== 
"Thread-1": 
    at Deadlock$Friend.bowBack(Deadlock.java:16) 
    - waiting to lock <0x8b80def8> (a Deadlock$Friend) 
    at Deadlock$Friend.bow(Deadlock.java:13) 
    - locked <0x8b80df08> (a Deadlock$Friend) 
    at Deadlock$2.run(Deadlock.java:28) 
    at java.lang.Thread.run(Thread.java:619) 
"Thread-0": 
    at Deadlock$Friend.bowBack(Deadlock.java:16) 
    - waiting to lock <0x8b80df08> (a Deadlock$Friend) 
    at Deadlock$Friend.bow(Deadlock.java:13) 
    - locked <0x8b80def8> (a Deadlock$Friend) 
    at Deadlock$1.run(Deadlock.java:25) 
    at java.lang.Thread.run(Thread.java:619) 

Found 1 deadlock. 

Так что, когда у вас есть затор под рукой VM может обнаружить и показать его.