我们何时在处理“ GET”的java方法上使用Synchronized?

时间:2019-07-17 11:43:22

标签: java multithreading web concurrency thread-safety

试图了解并发概念。  我看到了带有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<>(...){....} 

我的问题是,这两个方法是否在同一个类中,并且由于同步方法锁定了该类的整个对象,因此它也锁定了非同步方法吗?

2 个答案:

答案 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
}

非同步方法不会阻塞任何东西。