试图了解并发概念。 我看到了带有Controller类的springboot应用程序,该类具有2种方法:
@RequestMapping(value = "/r1", produces = "application/json; charset=utf-8", method = RequestMethod.GET)
@ResponseBody
public ResponseEntity<> function1(...){...}
和另一个同班的人:
@RequestMapping(value = "/r2", produces = "application/json; charset=utf-8", method = RequestMethod.GET)
@ResponseBody
public synchronized ResponseEntity<>(...){....}
我的问题是,这两个方法是否在同一个类中,并且由于同步方法锁定了该类的整个对象,因此它也锁定了非同步方法吗?
答案 0 :(得分:1)
问题:我的问题是,这两个方法是否在同一个类中,并且由于同步方法锁定了该类的整个对象,所以它也锁定了非同步方法吗? / p>
答案:不,在所有其他线程尝试在同一对象上调用同步方法时,仅同步方法将被阻止。
Synchronized Methods从文档中可以明显看出,一次只有一个线程可以在对象上执行同步方法,而所有其他试图在同一对象上执行同步方法的线程将被阻塞。
但是,如果两个线程使用两个不同的对象,它们仍然可以一次执行同步方法
首先,不可能对同一对象的两次同步方法调用进行交织。当一个线程正在为一个对象执行同步方法时,所有其他为同一对象块调用同步方法的线程(暂停执行),直到对象完成第一个线程。
第二,当同步方法退出时,它会自动与之前对同一对象的同步方法的任何调用建立先发生关系。这样可以保证对对象状态的更改对所有线程都是可见的。
答案 1 :(得分:0)
如果您有一个同步块,则必须给它一个对象以锁定,如下所示:
Object o = new Object();
synchronized (o) {
// do something
}
如果需要,可以使用this
而不是o
来使用对象实例本身,如下所示:
synchronized (this) {
// do something
}
如果您有两种方法,并且想要一个保护这两种方法的锁,则可以执行以下操作:
Object o = new Object();
public void methodOne() {
synchronized (o) {
// do something
}
}
public void methodTwo() {
synchronized (o) {
// do something
}
}
和以前一样,您可以使用this
代替单独的对象o
,如下所示:
public void methodOne() {
synchronized (this) {
// do something
}
}
public void methodTwo() {
synchronized (this) {
// do something
}
}
或者您可以通过将两个方法都标记为sychronized
来实现相同的目的,因为同步方法将锁定对象实例:
public synchronized void methodOne() {
// do something
}
public synchronized void methodTwo() {
// do something
}
非同步方法不会阻塞任何东西。