我正在阅读有关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()
吗?
答案 0 :(得分:4)
否,两个线程无法同时运行方法eat
和eatDinner
。 (警告:只要在类的相同的实例上调用这些方法)
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同时完成eatDinner
和eat
<强>增加:强> 回应您的评论
@Raj:如果两个线程是由相同的类实例创建的,那么?
线程的创建方式并不重要 - 如果这些线程来自同一个类或代码中完全不同的位置,则无关紧要。两个不同的线程始终是独立的。
只关注您同步的对象监视器:每个对象实例都有一个监视器&#39;。您无法看到此显示器 - 它没有名称,但它在那里,synchronized
关键字和wait
,{{{在notify
中定义的1}}和notifyAll
方法。
答案 1 :(得分:2)
&#34;现在2个线程可以调用eat()而另一个eatDinner()可以同时运行吗? &#34;
在同一个实例上,没有。它们会阻塞,只有一个会立即执行。不同的类实例,是的,它们不会阻止其他类。
&#34; thread1可以从eat()&#34;
调用eatDinner()是肯定的。锁是可重入的。
答案 2 :(得分:1)
如果2个线程在不同的类实例上调用方法,则它们可以同时运行方法