当前位置: 首页 > 知识库问答 >
问题:

Springboot异步方法在同一线程中运行

艾善
2023-03-14

我正在spring-boot 2中测试@Async,并遵循了一些在线教程

我的配置类:

@Configuration
@EnableAsync
public class AsyncConfig {

    @Bean
    public Executor asyncExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(5);
        executor.setMaxPoolSize(5);
        executor.setQueueCapacity(500);
        executor.setThreadNamePrefix("Async Process-");
        executor.initialize();
        return executor;
    }
}

我的控制器片段:

@GetMapping("/test/async")
public void testAsync() {
    System.err.println("Thread in controller: " + Thread.currentThread().getName());
    TestAsyncClazz clazz = new TestAsyncClazz();
    clazz.testAsyncMethod();
}

我的<code>TestAsyncClass</code>:

public class TestAsyncClazz {

    @Async
    public void testAsyncMethod(){
        System.err.println("Running async: "+ Thread.currentThread().getName());
    }
}

当我检查打印行时,它显示我的两个方法都在同一个线程上运行,并且它没有使用threadNamePrefix<code>Async Process-

Thread in controller: http-nio-8080-exec-2
Running async: http-nio-8080-exec-2

我做错了什么?我误会什么了吗?

共有1个答案

柳越
2023-03-14

发生这种情况是因为您在使用new实例化自己的类上调用async方法:

TestAsyncClazz clazz = new TestAsyncClazz();
clazz.testAsyncMethod();

如果您这样做,Spring就没有机会使用必要的代理类来装饰实例,该代理类提供了异步运行方法的实际功能

这只会以您在Springbeans上期望的方式工作——换句话说,不要自己实例化TestAsyncClazz;定义类的Springbean实例,将该bean自动连接到控制器中,然后调用bean上的方法。

示例:

@Configuration
@EnableAsync
public class AsyncConfig {

    @Bean
    public Executor asyncExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(5);
        executor.setMaxPoolSize(5);
        executor.setQueueCapacity(500);
        executor.setThreadNamePrefix("Async Process-");
        executor.initialize();
        return executor;
    }

    // Define a Spring bean of type TestAsyncClazz
    @Bean
    public TestAsyncClazz testAsyncClazz() {
        return new TestAsyncClazz();
    }
}

@Controller
public class MyController {

    // Inject the bean here
    @Autowired 
    private TestAsyncClazz testAsyncClass;

    @GetMapping("/test/async")
    public void testAsync() {
        System.err.println("Thread in controller: " +
                Thread.currentThread().getName());

        // Use the bean instead of instantiating the class yourself
        testAsyncClass.testAsyncMethod();
    }
}
 类似资料:
  • 我了解Class对象上的静态同步锁,以及Object实例上的非静态锁。 但是,在此问题的可接受答案中:同步块中的静态与非静态锁定对象 使用非静态锁定对象时: 线程1调用o1.foo() 线程2调用o1.foo(),将不得不等待线程1完成 线程3调用o2.foo(),它可以只继续,不介意线程1和2 为什么线程 3 可以继续而不考虑线程 1 和 2。线程 3 是否必须等待从线程 1 或 2 获取对象实

  • 是否可以调用一个异步方法,以便它从一个同步的方法异步运行?我不关心它挂起同步调用程序直到它返回,而是希望该方法被异步调用。

  • 本文向大家介绍C# 线程同步的方法,包括了C# 线程同步的方法的使用技巧和注意事项,需要的朋友参考一下 一、进程内部的线程同步 1、使用lock,用法如下: 特性:只能传递对象,无法设置等待超时 2、使用:InterLocked(原子操作) 其在System.Threading命名空间下,Interlocked实际是类控制计数器,从而实现进程的同步,其很容易实现生产者消费者模型 3、使用Monit

  • 在ViewComponent中,我得到了以下警告:(我使用了) 更新: 在视图中,我有:

  • 我有以下代码要测试: 这是我使用进行的JUnit测试: 如果我这样运行它,则检查状态的最后一次验证将失败。如果添加,它就会通过。是否有更好或更安全的方法通过测试,而不添加方法?

  • 当我尝试通过启动不同的线程来执行所有同步方法时,我在一个类中有三个同步方法,我看不到同步的输出,在对象上没有获得锁 公共类DisplayMessage{ }线程类: 公共类 MyThread 扩展了线程 { }Thread2类:公共类MyThread2扩展线程{ } 线程 3 类: 包装Synchronization.classlock; 公共类MyThread3扩展线程{ } 使用main方法生

  • 警告试着告诉我什么?我该怎么办? 这是我的代码:它是否使用多线程运行?

  • 问题内容: 我在同一文件中有以下程序。我已经同步了run()方法。 输出是 我的问题是,为什么同步方法同时允许“我的线程1”和“我的线程4”线程访问? 问题答案: 方法在实例级别工作。 类的每个实例都有自己的锁。每次输入实例的任何方法都将获取该锁。这样可以防止多个线程 在同一个实例上 调用方法(请注意,这还可以防止在同一个实例上调用 不同的 方法)。 现在,由于您有两个类实例,因此每个实例都有自己