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

我正在阅读有关JAVA同步的内容。

我class上有两种方法。

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

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

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

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

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

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

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

这可能使它更容易看到它们在同一台监视器上同步。 每个java对象都有一个监视器

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

所以thread1可以调用eatDinner如果它已经在eat方法中 – 没问题。 但是如果thread2当前在eat方法中,那么thread1会在调用eatDinnereatDinner直到thread2完成eatDinnereat

增加:回应你的评论

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

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

只关注同步哪个对象的监视器:每个对象实例都有一个“监视器”。 您无法看到此监视器 – 它没有名称,但它在那里,它由synchronized关键字以及java.lang.Object定义的waitnotifynotifyAll方法使用。

“现在有两个线程可以调用eat()而另一个eatDinner()可以同时运行吗?”

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

“thread1可以从eat()调用eatDinner()”

是。 锁是可重入的。

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