[英]Executing two synchronized method by two thread in java
可以说我在类ABC
有synchronized hi(){}
和synchronized hello(){}
方法的方法。 两个线程t1
和t2
分别执行t1.hi()
和t2.hello()
。 它们可以同时执行还是存在任何问题?
否,同一对象中的2个同步方法不能同时执行:
https://docs.oracle.com/javase/tutorial/essential/concurrency/syncmeth.html
从文档:
在同一个对象上两次同步方法调用是不可能交织的。 当一个线程正在执行对象的同步方法时,所有其他调用同一对象块的同步方法的线程(挂起执行),直到第一个线程对该对象完成。
这里的关键是锁定在对象上。 正如Thomas所指出的,大概t1
和t2
是同一类的不同实例,因此它们实际上可以同时执行hi()
和hello()
。
如果t1
和t2
仅是在同一对象上调用hi()
和hello()
2个不同线程,则上述语义成立,并且这2个方法不能并行执行。
在方法声明中使用synced关键字使用隐式对象,对于静态方法,它是类对象;对于非静态方法,是实例对象本身。
范例1:
public class A {
public synchronized void setName() {
//
}
public synchronized void setAge() {
//
}
}
假设有两个线程Thread-1和Thread-2。
现在线程1尝试访问setName()和线程2 setAge()
让线程1输入1st并按住密钥,线程2将等待直到密钥可用。 困惑?
因此,由于没有显式对象用于同步,因此使用相同的密钥来同步两个
“ A的对象,分别用于通过线程1和线程2访问setName()方法和setAge()方法”。
A a = new A("Name", 1);
Runnable nameR = () -> a.getName();
Runnable ageR = () -> a.getAge();
Thread nameThread = new Thread(nameR);
Thread ageThread = new Thread(nameR);
nameThread.start();
ageThread.start();
但这是有问题的,因为即使具有密钥的线程无法访问它,也没有其他线程能够运行其他方法。
因此,要解决此问题,我们需要有单独的键来独立同步getName和getAge方法。
public class A {
private final Object nameLock = new Object();
private final Object ageLock = new Object();
public void setName() {
synchronized(nameLock) {
//
}
}
public synchronized void setAge() {
synchronized(ageLock) {
//
}
}
}
希望这可以帮助!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.