两个线程执行两个`synchronized`方法?

时间:2014-03-16 05:49:05

标签: java multithreading synchronized

我正在阅读有关JAVA同步的信息。

我班上有两种方法。

public synchronized void eat()
{
    System.out.println("eat");
    eatDinner();
}

public synchronized void eatDinner()
{
    System.out.println("eat");
}

我的两个方法都是同步的。

现在是否有可能2个线程正在调用eat()而另一个eatDinner()同时运行? 如果thread2还没有执行eatDinner()。 thread1可以从eatDinner()调用eat()吗?

3 个答案:

答案 0 :(得分:4)

,两个线程无法同时运行方法eateatDinner。 (警告:只要在类的相同的实例上调用这些方法)

synchronized关键字应用于非静态方法时,会在对象本身上进行同步。

您的代码可以在不改变含义的情况下重写,如下:

public void eat() {
    synchronized (this) {
        System.out.println("eat");
        eatDinner();
    }
}

public void eatDinner() {
    synchronized (this) {
        System.out.println("eat");
    }
}

这可能会让他们更容易看到他们在同一个监视器上同步。 每个java对象都有一个 monitor

只要' thread1'拿着对象的监视器,它可以在同一监视器上输入其他synchronized块。 '线程1'必须退出所有同步的块(存在块的次数与它们输入的次数相同),然后另一个线程才能获得监视器的所有权。

所以如果线程1已经在eatDinner方法中,那么它可以调用eat - 没问题。但如果thread2方法中当前有eat,则thread1会在调用eatDinner时阻止,直到thread2同时完成eatDinnereat

<强>增加: 回应您的评论

  

@Raj:如果两个线程是由相同的类实例创建的,那么?

线程的创建方式并不重要 - 如果这些线程来自同一个类或代码中完全不同的位置,则无关紧要。两个不同的线程始终是独立的。

只关注您同步的对象监视器:每个对象实例都有一个监视器&#39;。您无法看到此显示器 - 它没有名称,但它在那里,synchronized关键字和wait,{{{在notify中定义的1}}和notifyAll方法。

答案 1 :(得分:2)

&#34;现在2个线程可以调用eat()而另一个eatDinner()可以同时运行吗? &#34;

在同一个实例上,没有。它们会阻塞,只有一个会立即执行。不同的类实例,是的,它们不会阻止其他类。

&#34; thread1可以从eat()&#34;

调用eatDinner()

是肯定的。锁是可重入的。

答案 2 :(得分:1)

如果2个线程在不同的类实例上调用方法,则它们可以同时运行方法