提问人:elvis 提问时间:8/21/2023 最后编辑:Mureinikelvis 更新时间:8/21/2023 访问量:73
如果 Java 中的监视对象不同,是否可以 2 个线程执行相同的同步实例方法?
Could 2 threads execute the same synchronized instance method if the monitor object is different in Java?
问:
我是 Java 并发的新手,我知道同步的实例方法意味着一次只有一个线程可以执行该方法。但是这件事是否取决于监视对象?如果监视对象不同,是否可以同时执行相同的同步实例方法?
例如:这是一个例子,但我不确定它是否是一个好例子。我只是想知道是否可以同时调用同步方法或阻止两个或多个线程。或者始终无法调用同步方法
public class SynchronizedExchanger {
protected Object object = null;
public synchronized void setObject(Object o) {
System.out.println("Do something, o = " + o);
this.object = o;
}
}
public class SynchronizedExchangerMainDemo {
public static void main(String[] args) {
SynchronizedExchanger exchanger = new SynchronizedExchanger();
SynchronizedExchanger exchanger1 = new SynchronizedExchanger();
Thread thread1 = new Thread(
new Runnable() {
@Override
public void run() {
for (int i = 0; i < 1000; i++) {
exchanger.setObject("" + i);
}
}
}
);
Thread thread2 = new Thread(
new Runnable() {
@Override
public void run() {
for (int i = 0; i < 1000; i++) {
exchanger1.setObject("" + i);
}
}
}
);
}
}
答:
如果实例方法声明为 ,这意味着它在 上隐式同步,因此根据定义,受监视的对象将是相同的,并且只有一个线程可以在给定时间执行该方法。synchronized
this
如果该方法未声明为 ,而是使用显式块,则仅使用相同的监视对象将阻止并发执行。如果两个线程使用不同的监视器对象,则它们可以并发执行。synchronized
synchronized
评论
static
this
Class
synchronized
exchanger.setObject
exchanger
exchanger1.setObject
exchanger1
,并引用两个不同的实例。这两个线程绝对可以“同时”调用,因为 是同步的,并且引用一个线程中的实例,但它引用另一个线程中的实例。exchanger
exchanger1
setObject
setObject
this
this
exchanger
exchanger1
synchronized(o)
仅防止多个线程同时在同一个对象 o
上同步。当你写的时候:
synchronized MyType mymethod(...) {
doSomeStuff(...);
return something;
}
这只是以下方面的捷径:
MyType mymethod(...) {
synchronized(this) {
doSomeStuff(...);
return something;
}
}
如果只有一个实例,并且两个线程都在它上运行,那就不同了。在这种情况下,将在两个线程中引用同一个对象,并且两个线程在任何时候都不允许同时位于该对象上。SynchronizedExchanger
this
synchronized
监视器是互斥锁,它是线程为了获得对同步代码的独占访问权限而获取的东西。例如,方法,监视器位于对象实例上,对于静态方法,监视器位于类对象上。
因此,如果两个线程没有获取相同的监视器,则也不会将另一个线程排除在外。
评论