Java 什么时候在处理';获取';?

Java 什么时候在处理';获取';?,java,multithreading,web,concurrency,thread-safety,Java,Multithreading,Web,Concurrency,Thread Safety,试图理解并发概念。 我看到了一个springboot应用程序,其控制器类有两个方法: @RequestMapping(value = "/r1", produces = "application/json; charset=utf-8", method = RequestMethod.GET) @ResponseBody public ResponseEntity<> function1(...){...} @RequestMapping(value=“/r1”,products=

试图理解并发概念。 我看到了一个springboot应用程序,其控制器类有两个方法:

@RequestMapping(value = "/r1", produces = "application/json; charset=utf-8", method = RequestMethod.GET)
@ResponseBody
public ResponseEntity<> function1(...){...}
@RequestMapping(value=“/r1”,products=“application/json;charset=utf-8”,method=RequestMethod.GET)
@应答器
公共响应职能1(…){…}
和同一类中的另一个:

  @RequestMapping(value = "/r2", produces = "application/json; charset=utf-8", method = RequestMethod.GET)
@ResponseBody
public synchronized ResponseEntity<>(...){....} 
@RequestMapping(value=“/r2”,products=“application/json;charset=utf-8”,method=RequestMethod.GET)
@应答器
公共同步响应性(…){…}

我的问题是,如果两个方法都在同一个类中,并且由于同步方法锁定了该类的整个对象,那么它不也锁定了非同步方法吗?

问题:我的问题是,如果两个方法都在同一个类中,并且由于同步方法锁定了该类的整个对象,它不也锁定非同步方法吗

回答:否,当所有其他线程尝试调用同一对象上的同步方法时,只有同步方法将被阻止

从文档中可以清楚地看到,一次只有一个线程可以在对象上执行synchronized方法,而尝试在同一对象上执行synchronized方法的所有其他线程都将被阻止

但是,如果两个线程使用两个不同的对象,那么它们仍然可以一次执行synchronized方法

首先,同一对象上的两个同步方法调用不可能交错进行。当一个线程为一个对象执行同步方法时,为同一对象块调用同步方法的所有其他线程(暂停执行),直到第一个线程处理完该对象。

其次,当同步方法退出时,它会自动与同一对象的同步方法的任何后续调用建立“发生在之前”关系。这保证了对象状态的更改对所有线程都可见


如果有一个同步块,则必须给它一个要锁定的对象,如下所示:

Object o = new Object();
synchronized (o) {
    // do something
}
synchronized (this) {
    // do something
}
public void methodOne() {
    synchronized (this) {
        // do something
    }
}
public void methodTwo() {
    synchronized (this) {
        // do something
    }
}
如果需要,可以通过使用
this
而不是
o
来使用对象实例本身,如下所示:

Object o = new Object();
synchronized (o) {
    // do something
}
synchronized (this) {
    // do something
}
public void methodOne() {
    synchronized (this) {
        // do something
    }
}
public void methodTwo() {
    synchronized (this) {
        // do something
    }
}
如果您有两个方法,并且需要一个锁来保护这两个方法,则可以执行以下操作:

Object o = new Object();
public void methodOne() {
    synchronized (o) {
        // do something
    }
}
public void methodTwo() {
    synchronized (o) {
        // do something
    }
}
与前面一样,您可以使用
this
而不是单独的对象
o
,如下所示:

Object o = new Object();
synchronized (o) {
    // do something
}
synchronized (this) {
    // do something
}
public void methodOne() {
    synchronized (this) {
        // do something
    }
}
public void methodTwo() {
    synchronized (this) {
        // do something
    }
}
或者,您也可以通过将这两种方法标记为“同步”,实现同样的效果,因为同步方法将锁定对象实例:

public synchronized void methodOne() {
    // do something
}
public synchronized void methodTwo() {
    // do something
}

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

“它不会也锁定非同步方法吗?”不会。同步(实例)方法只是一种方法,其中主体被包装在
synchronized(this){/*body*/}
中。同步不会以您建议的方式“锁定”任何东西。它只确保一次只执行一个同步序列。不同步的代码不受影响。