Spring的@Async忽略同步?

时间:2018-01-15 16:05:39

标签: java spring asynchronous synchronized

我在Service class中有这个方法:

@Service
public class Service {
    @Async
    public synchronized void asyncTest() {
        try {
            System.out.println("entered");
            Thread.sleep(5000);
            System.out.println("exited");
            System.out.println(this);
        }
        catch (InterruptedException e ) {}
    }
}

当我打电话

@Test
public void asyncTest() throws InterruptedException {
    service.asyncTest();
    service.asyncTest();
    Thread.sleep(10000);
}

它产生:

entered
entered
exited
exited
...Service@26d74d5f 
...Service@26d74d5f 

虽然我希望

entered
exited
...Service@26d74d5f 
entered
exited
...Service@26d74d5f 

由于synchronized关键字。为什么呢?

我的xml配置:

<task:annotation-driven mode="aspectj" executor="fisExecutor" scheduler="fisScheduler"/>
<task:executor id="fisExecutor" pool-size="10" />
<task:scheduler id="fisScheduler" pool-size="30" />
<task:executor keep-alive="60" id="cmsExecutor" pool-size="5-00" queue-capacity="0" rejection-policy="CALLER_RUNS"/>

Spring版本:4.1.9.RELEASE JDK 1.7

测试类注释:

   @RunWith(SpringJUnit4ClassRunner.class)
   @ContextConfiguration(locations = "classpath*:/applicationContext-*.xml")

1 个答案:

答案 0 :(得分:1)

一种方法是更改​​方法签名,以确保从您可以控制的API中获取异步对象。例如,您可以修改代码以包含CompletableFutures,模仿如下所示:

  @Service
  public class Service {
      @Async
      public CompletableFuture<Void> asyncTest() {
          try {
              System.out.println("entered");
              Thread.sleep(5000);
              System.out.println("exited");
              System.out.println(this);
          }
          catch (InterruptedException e ) {}

          return new AsyncResult<Void>(null);
      }
  }

我将此网站用于代码段和调查资源:http://www.baeldung.com/spring-async