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 но он может ожидать других ресурсов от такой как процессор.
Как я могу выяснить, что ждет поток?
Ответы
Ответ 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 не знает (не "управляет", следовательно, является "родным" фреймом) состояние вызова.