Как несколько потоков "заблокированы" на одном и том же объекте (как показано в дампе потока)
У меня есть следующий поток-дамп, который показывает, что два потока блокируются на одном и том же объекте. И я не понимаю, что это значит на самом деле
"pool-1-thread-2" prio=10 tid=0x00007fd6dc106000 nid=0x5d15 in Object.wait() [0x00007fd6d2067000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x00000007c3547770> (a java.lang.Object)
at java.lang.Object.wait(Object.java:503)
at test.TestDead$Foo.second(TestDead.java:22)
at test.TestDead$Foo.first(TestDead.java:14)
- locked <0x00000007c3547770> (a java.lang.Object)
at test.TestDead$2.run(TestDead.java:45)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
at java.util.concurrent.FutureTask.run(FutureTask.java:262)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:724)
Locked ownable synchronizers:
- <0x00000007c35519e8> (a java.util.concurrent.ThreadPoolExecutor$Worker)
"pool-1-thread-1" prio=10 tid=0x00007fd6dc104800 nid=0x5d14 in Object.wait() [0x00007fd6d2168000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x00000007c3547770> (a java.lang.Object)
at java.lang.Object.wait(Object.java:503)
at test.TestDead$Foo.second(TestDead.java:22)
at test.TestDead$Foo.first(TestDead.java:14)
- locked <0x00000007c3547770> (a java.lang.Object)
at test.TestDead$1.run(TestDead.java:37)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
at java.util.concurrent.FutureTask.run(FutureTask.java:262)
atjava.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
atjava.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:724)
Locked ownable synchronizers:
- <0x00000007c3551730> (a java.util.concurrent.ThreadPoolExecutor$Worker)
Что на самом деле означает "заблокирован"?
1 ответ
В этом контексте заблокированный означает, что ваш работающий Java-код ввел synchronous
блок, но еще не вышел из этого блока.
Как показывает ваш дамп, вы звоните wait()
который внутренне разблокирует монитор, связанный с synchronous
блок. Однако, поскольку вы блокируете при ожидании и не вышли из синхронного блока, поток-дамп все еще показывает locked
, Таким образом, возможно отображение нескольких потоков locked
в дампе потока, несмотря на то, что основной монитор разблокирован.
Это можно легко продемонстрировать с помощью простого теста:
public class TestMonitor {
synchronized public void lockAndWait() {
try {
wait();
} catch ( InterruptedException ex ) {
// Stifle
}
}
public static void main( String args[] ) {
TestMonitor tm = new TestMonitor();
tm.lockAndWait();
}
}
который выводит следующий поток-дамп при запуске:
"main" prio=10 tid=0x00007f86c4008000 nid=0x5d35 in Object.wait() [0x00007f86cbae2000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x0000000759055df8> (a TestMonitor)
at java.lang.Object.wait(Object.java:503)
at TestMonitor.lockAndWait(TestMonitor.java:5)
- locked <0x0000000759055df8> (a TestMonitor)
at TestMonitor.main(TestMonitor.java:13
Обратите внимание, что монитор все еще locked
несмотря на то, что в wait
,
ОБНОВИТЬ
В случае, если случай с одним потоком не убедителен, вы можете запустить приведенный выше пример, слегка измененный, в этом случае вы увидите несколько потоков locked
на том же мониторе в потоке-дампе:
public static void main( String args[] ) {
final TestMonitor tm = new TestMonitor();
Thread thread1 = new Thread( new Runnable() { public void run() { tm.lockAndWait(); } } );
Thread thread2 = new Thread( new Runnable() { public void run() { tm.lockAndWait(); } } );
thread1.start();
thread2.start();
}