Подтвердить что ты не робот

RUNNABLE Thread.State, но в Object.wait()

Я извлек JStack моего контейнерного процесса и получил потоки, работающие там со следующим распределением, сгруппированным по Thread.state:

count    thread state
   67    RUNNABLE
    1    TIMED_WAITING (on object monitor)
    8    TIMED_WAITING (parking)
    4    TIMED_WAITING (sleeping)
    3    WAITING (on object monitor)
   17    WAITING (parking)

Для исполняемых потоков у меня есть следующее описание:

"http-bio-8080-exec-55" daemon prio=10 tid=0x000000002cbab300 nid=0x642b in Object.wait() [0x00002ab37ad11000]
   java.lang.Thread.State: RUNNABLE
    at com.mysema.query.jpa.impl.JPAQuery.<init>(JPAQuery.java:44)
    at net.mbppcb.cube.repository.TransactionDaoImpl.findByBusinessId(TransactionDaoImpl.java:73)
    at sun.reflect.GeneratedMethodAccessor76.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:317)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:183)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
    at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:155)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
    ...

Количество потоков в состоянии RUNNABLE, как показано выше, увеличивается с временем и кажется, что оно висит. Если они предполагают быть заблокированными, разве они не должны находиться в состоянии БЛОКИРОВКИ? Или они должны быть в состоянии ОЖИДАНИЯ? Странно иметь потоки RUNNABLE, но в Object.wait() не так ли?

Обновление 1

Я вижу в документации:

Поток в состоянии runnable выполняется в виртуальном Java но он может ожидать других ресурсов от такой как процессор.

Как я могу выяснить, что ждет поток?

4b9b3361

Ответ 1

Это похоже на тупик инициализации класса .

JPAQuery конструктор ждет инициализации зависимого класса, возможно, JPAProvider:

    public JPAQuery(EntityManager em) {
        super(em, JPAProvider.getTemplates(em), new DefaultQueryMetadata());
    }

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

Зачем нужен поток в RUNNABLE состоянии?

Ну, это путаница внутри JVM HotSpot. Процедура инициализации класса реализована в среде выполнения VM, а не на Java-площадке, и блокировка класса захватывается изначально. Кажется, это причина, по которой состояние потока не было изменено, но я предполагаю, что это поведение должно быть исправлено и в JVM.

Ответ 2

Документация Oracle Thread.State указывает, что поток в заблокированном состоянии ожидает блокировки монитора, чтобы ввести синхронизированный блок/метод или после вызова вызовите синхронизированный блок/метод. Он не похож ни на один из потоков в режиме блокировки.

Ответ 3

Если все потоки Runnable, по-видимому, заблокированы в операциях с базой данных, я бы предложил использовать инструменты мониторинга/диагностики базы данных для изучения причины. После этого, возможно, исследуя ваш код базы данных, чтобы найти такие проблемы, как незавершенные транзакции, неправильные исключения, приводящие к незакрытым ресурсам.

Дампы потоков Java, вероятно, дали вам всю информацию, которую они могут в этот момент - указатель на то, где начать искать следующий.

Ответ 4

"Число потоков в состоянии RUNNABLE, как показано выше, увеличивается с время и кажется, что он висит".

Число RUNNABLES будет расти в зависимости от количества потоков, выполняющих метод "com.mysema.query.jpa.impl.JPAQuery". в то время, когда была сделана эта свалка. Этот метод фактически является конструктором класса JPAQuery, обозначаемым "init". Вам, вероятно, потребуется исследовать код в конструкторе и последующие вызовы реализации JPA.

Ответ 5

Object.wait() просто вызывает Object.wait(0) (ноль без таймаута). Реализация Object.wait(long):

public final native void wait(long timeout) throws InterruptedException;

Все потоки, которые находятся в собственном фрейме, RUNNABLE, поскольку JVM не знает (не "управляет", следовательно, является "родным" фреймом) состояние вызова.