栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

简单的@Async使用

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

简单的@Async使用

@Async使用

最简单的使用就是
springboot项目就直接在启动类上添加 @EnableAsync 就可以使用了
而ssm或者ssh可以在 xml配置



不过大多数的使用都会使用自定义的线程池,已防止高并发时出现OOM
使用方法也很简单,建立类

@Configuration
@EnableAsync
public class ThreadPoolConfig implements AsyncConfigurer  {


    private static final int CORE_POOL_SIZE = 20;

    private static final int MAX_POOL_SIZE = 50;

    private static final int QUEUE_CAPACITY = 200;

    
    @Override
    public Executor getAsyncExecutor() {
    	ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(CORE_POOL_SIZE);
        executor.setMaxPoolSize(MAX_POOL_SIZE);
        // 设置队列容量
        executor.setQueueCapacity(QUEUE_CAPACITY);
        // 设置线程活跃时间(秒)
        executor.setKeepAliveSeconds(60);
        //设置线程名前缀
        executor.setThreadNamePrefix("ThreadPool#Task");
        // 设置拒绝策略
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        executor.initialize();
        System.out.println("线程池创建了");
        return threadPoolTaskExecutor;
    }

    
}

这样就可以了 使用@Async 他就会使用这个自定义的线程池

如何验证呢,你可以在使用@Async方法里调用
System.out.println(“线程名称:” + Thread.currentThread().getName());
来查看线程名是否你在线程池定义的前缀

当然,你想使用其他自定义的线程池也是可以的,在@Async(XXXXX) 填入对应线程池的名字就可以使用了

使用@Async的注意事项

最多的失效情况应该是,在方法中调用了本类的 @Async方法,让 @Async方法没有失效,原因其实就是,@Async是spring的注解,自然使用的对象是spring里的动态代理对象,就是加注解 @Autowired 这样的使用,而你调用本类方法的使用,直接就是使用 this.xxx,进行内部调用,自然@Async就没有获取到对象
解决
要不就写在另一个类, 要不就 @Autowired 自己 ,
要不就从上下文获取 SysAuditService sysLogService=(SysAuditService) Util.getMyEnginBean(“sysAuditService”);

@Async在Hibernate的坑

在 @Async 里使用 HibernateTemplate执行sql 它会报 no session 异常 因为线程里没有 Hibernate session ,没解决方法也很简单,没有就绑一个就可以了

new Runnable() {
                @Override
                public void run() {
//                  ----------绑定session到当前线程------------
                    SessionFactory sessionFactory = (SessionFactory)applicationContext.getBean("sessionFactory");
                    boolean participate = ConcurrentUtil.bindHibernateSessionToThread(sessionFactory);
//                  ---------你的业务---------------
//                  ----------关闭session------------                   
                    ConcurrentUtil.closeHibernateSessionFromThread(participate, sessionFactory);
                }
                
            }

bindHibernateSessionToThread方法:

public static boolean bindHibernateSessionToThread(SessionFactory sessionFactory) {
        if (TransactionSynchronizationManager.hasResource(sessionFactory)) {
            // Do not modify the Session: just set the participate flag.
            return true;
        } else {
            Session session = sessionFactory.openSession();
            session.setFlushMode(FlushMode.MANUAL);
            SessionHolder sessionHolder = new SessionHolder(session);
            TransactionSynchronizationManager.bindResource(sessionFactory, sessionHolder);
        }
        return false;
    }

closeHibernateSessionFromThread方法

 public static void closeHibernateSessionFromThread(boolean participate, Object sessionFactory) {
 
        if (!participate) {
            SessionHolder sessionHolder = (SessionHolder)TransactionSynchronizationManager.unbindResource(sessionFactory);
            SessionFactoryUtils.closeSession(sessionHolder.getSession());
        }
    }

这样就可以了

参考:https://blog.csdn.net/zhengwei223/article/details/30506455

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/340721.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号