简体   繁体   English

怎样才能有多个线程“锁定”在同一个对象上(如线程转储中所示)

[英]how can more than one thread have “locked” on the same object (as shown in a thread-dump)

I have the following thread-dump, which shows two threads both locking on the same object. 我有以下线程转储,它显示两个线程都锁定在同一个对象上。 And I'm confused as to what it really means 我对它的真正含义感到困惑

    "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)

What does "locked" really mean here? “锁定”在这里意味着什么?

In this context, locked means that your running java code has entered a synchronous block but not yet exited that block. 在此上下文中, locked表示您正在运行的java代码已进入synchronous块但尚未退出该块。

As your thread-dump shows, you are calling wait() which internally unlocks the monitor associated with the synchronous block. 在您的线程转储显示时,您正在调用wait() ,它在内部解锁与synchronous块关联的监视器。 However, since you are blocking on wait and have not exited the synchronous block, the thread-dump still shows locked . 但是,由于您在等待时阻塞并且未退出同步块,因此线程转储仍显示已locked Thus it is possible to have multiple threads display locked in the thread-dump despite the fact that the underlying monitor is unlocked. 因此,尽管底层监视器已解锁,但仍有可能在线程转储中locked多个线程。

This can be easily demonstrated with a simple test: 通过简单的测试可以很容易地证明这一点:

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();
    }
}

which outputs the following thread-dump when run: 运行时输出以下线程转储:

"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

Note the monitor is still locked despite being in wait . 请注意,尽管wait ,显示器仍处于locked状态。

UPDATE UPDATE

In the event the single thread case isn't convincing, you can run the above example slightly modified in which case you'll see multiple threads locked on the same monitor in the thread-dump: 如果单线程情况不令人信服,您可以运行稍微修改的上述示例,在这种情况下,您将看到在线程转储中的同一监视器上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();
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM