两个线程执行两个`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
同时运行方法eat
和eatDinner
。 (警告:只要在类的同一个实例上调用这些方法)
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
会在调用eatDinner
时eatDinner
直到thread2完成eatDinner
和eat
。
增加:回应你的评论
@Raj:如果两个线程是由同一个类实例创建的,那么呢?
创建线程的方式并不重要 – 如果发生在同一个类中或代码中完全不同的位置,则无关紧要。 两个不同的线程始终是独立的。
只关注同步哪个对象的监视器:每个对象实例都有一个“监视器”。 您无法看到此监视器 – 它没有名称,但它在那里,它由synchronized
关键字以及java.lang.Object
定义的wait
, notify
和notifyAll
方法使用。
“现在有两个线程可以调用eat()而另一个eatDinner()可以同时运行吗?”
在同一个实例上,没有。 它们会阻塞,只有一个会立即执行。 不同的类实例,是的,它们不会阻止其他类。
“thread1可以从eat()调用eatDinner()”
是。 锁是可重入的。
如果2个线程在不同的类实例上调用方法,则它们可以同时运行方法