为什么同步父类没有阻止以下代码?

时间:2014-05-26 12:22:38

标签: java multithreading

import java.util.Date;

class AppParent {
    public synchronized void doSomething() {
        System.out.println(new Date() + " : " + Thread.currentThread().getName() + " Inside AppParent");
        try {
            Thread.sleep(15000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        System.out.println(new Date() + " : " + Thread.currentThread().getName() + " Exiting AppParent");
    }
}

class AppChild extends AppParent {
    public synchronized void doSomething() {
        System.out.println(new Date() + " : " + Thread.currentThread().getName() + " Inside AppChild");
        super.doSomething();
        System.out.println(new Date() + " : " + Thread.currentThread().getName() + " Exiting AppChild");
    }
}

public class App {
    public static void main(String... args) {
        Thread t1 = new Thread(new Runnable() {

            @Override
            public void run() {
                new AppParent().doSomething();
            }
        });
        t1.setName("Thread 1");

        Thread t2 = new Thread(new Runnable() {

            @Override
            public void run() {
                new AppChild().doSomething();
            }
        });
        t2.setName("Thread 2");

        t1.start();
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        t2.start();
    }
}

输出:

Mon May 26 17:45:02 IST 2014 : Thread 1 Inside AppParent
Mon May 26 17:45:03 IST 2014 : Thread 2 Inside AppChild
Mon May 26 17:45:03 IST 2014 : Thread 2 Inside AppParent
Mon May 26 17:45:17 IST 2014 : Thread 1 Exiting AppParent
Mon May 26 17:45:18 IST 2014 : Thread 2 Exiting AppParent
Mon May 26 17:45:18 IST 2014 : Thread 2 Exiting AppChild

我的问题: 如果线程1在父类同步方法内(它将花费15秒),线程2如何进入同一个同步块?

我期望在打印线程1内部AppParent后15秒内打印出Thread 2 Inside AppParent。

有人可以解释一下。 谢谢!

1 个答案:

答案 0 :(得分:2)

他们可以进入,因为它是不同对象的关键部分。 (同一类,但不同的对象。)

@Override
public void run() {
    new AppParent().doSomething();
}

您同步对象。创建一个新对象会生成另一个Thread可以进入的新同步监视器。