想知道是否有人可以帮我解决这个问题。 (学生)
假设我们有两个主题," Thread1" &安培; "线程2&#34 ;.如果Thread1在方法1中执行,那么Thread2可以在method2中执行吗?
void method1() {
synchronized (this) {
}
}
void method2() {
synchronized (this) {
}
}
我想是的,Thread2可以输入"这个"只是那个方法的实例或者没有因为"这个"是该类的实例,Thread1保留在它上面。
答案 0 :(得分:9)
没有与特定方法相关联的监视器 - 有一个与对象相关联的监视器。因此,如果您尝试在两个方法中同步对象,则第二个线程将阻塞,直到第一个线程释放监视器。
(就我个人而言,我不喜欢在this
上进行同步 - 我同步对一个仅我的班级有权访问的对象的引用。但这是另一回事。)< / p>
答案 1 :(得分:4)
每个人都在这里找到了明显的答案。这是一个正确的答案,但它不是唯一的正确答案。
规则是,两个线程不能同时在同一个对象上同步。但this
是否在两个方法调用中引用相同的对象?我们无法分辨,因为您没有向我们展示电话。考虑这个例子:
class Demo {
synchronized void method1() {
...do something...
}
synchronized void method2() {
...do something else...
}
static void caseA() {
final Demo demo = new Demo();
new Thread(new Runnable(){
@Override
public void run() {
demo.method1();
}
}).start();
new Thread(new Runnable(){
@Override
public void run() {
demo.method2();
}
}).start();
}
static void caseB() {
final Demo demo1 = new Demo();
final Demo demo2 = new Demo();
new Thread(new Runnable(){
@Override
public void run() {
demo1.method1();
}
}).start();
new Thread(new Runnable(){
@Override
public void run() {
demo2.method2();
}
}).start();
}
}
在caseA()中,对demo.method1()和demo.method2()的调用不能重叠,因为两个调用在同一个对象上同步,但在caseB()中,两个调用在两个上同步Demo类的实例。在caseB()中,method1()调用和method2()调用可以重叠。
答案 2 :(得分:3)
您正在使用this
进行同步,这是一个对象的实例。同步始终适用于某个特定的对象实例,并且在任何给定时间只有一个线程可以获取(同步)用于同步的单个实例的锁定。
两个线程只有在使用包含这些方法的对象的单独实例时才能访问这些方法。
答案 3 :(得分:1)
第二个线程将阻塞,直到第一个线程被第一个线程释放,因为两个方法在同一个对象上进行了同步。
答案 4 :(得分:1)
您最好在要锁定的静态对象上进行同步。
这里,您的方法2将由线程2执行,但方法2中的synchronized
块的内容将不会被执行,除非线程1已解锁this
。由于您的同步是在块上而不是在方法上,因此该方法不同步,但块是。
如果您有一个静态成员,您希望在同步中使用它,请使用它:
private static List<Object> myList;
void method1() {
synchronized (myList) {
// do something on myList
}
}
void method2() {
synchronized (myList) {
// do something on myList
}
}
答案 5 :(得分:0)
没有Thread2必须等到Thread1完成在synchronized块中执行代码。这是因为您使用相同的对象(this)来锁定。如果你做了这样的事情:
Object lock1 = new Object();
Object lock2 = new Object();
void method1() {
synchronized (lock1) { }
}
void method2() {
synchronized (lock2) { }
}
然后你就可以让Thread1执行method1而Thread2执行method2。