spring mvc的controller默认是单例还是多例(四)

controller 是单例模式还是多例模式

springmvc controller默认的是单例singleton的,单例模式是spring推荐的配置,它在高并发下能极大的节省资源,提高服务抗压能力。采用单例模式的好处:

  • 为了性能,单例不用每次都new,当然快了。
  • 不需要多例,这是官方说法。

单例模式下容易出现的问题就是controller中定义很多的属性,那么单例肯定会出现竞争访问,不同用户共享数据变量是不安全的。因此:

  • 不要在controller中定义成员变量。
  • 万一必须要定义一个非静态成员变量时候,则通过注解@Scope("prototype"),将其设置为多例模式。
@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
  • 在Controller中使用ThreadLocal变量

当然可以修改controller 为多列模式,通过@controller之前增加@Scope("prototype"),或者配置文件定义修改。
Struts2默认的实现是Prototype模式,Struts2中的Action因为会有User、BizEntity这样的实例对象,是有状态信息的,在多线程环境下是不安全的,所以是多例。

单例模式下的高并发线程池处理

在很多场景都会遇到高并发情况:"短时间内遇到大量操作请求"。主要发生在web系统集中大量访问或者socket端口集中性收到大量请求。该情况的发生会导致系统在这段时间内执行大量操作,例如对资源的请求,数据库的操作等。处理不好,可能导致系统宕机,严重的甚至导致OOM异常,系统停止工作等。
实际工作,我们可以使用线程池技术作为处理高并发的手段之一,解决部分问题。

比如:查询推荐商品数据接口,请求此接口访问高并发,并且接口返回数据时间长,在这种高并发的情况下不使用线程池:

  • 可能造成系统创建大量线程而导致消耗完系统内存以及”过度切换”(1W请求同时执行,创建1W线程),导致宕机。
  • 接口查询速度本身就慢,又同时访问对数据库服务器造成很大的压力。

如果使用线程池,能解决以下问题:

  • 有效的降低了线程创建释放的时间花销及资源开销。
  • 有效控制最大并发线程数,降低了同时请求数(线程池设置线程数量上限,超过则排队等候)。
  • 充分重复利用线程。

例如:

//工作线程的创建数量几乎没有限制(其实也有限制的,数目为Interger. MAX_VALUE)
//如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程
private ExecutorService threadPoolExecutor = Executors.newCachedThreadPool();
private Future<APIGoodsRecommendResponse> getAPIGoodsRecommendResponse(
            final APIGoodsRecommendRequest apiGoodsRecommendRequest){

        return threadPoolExecutor.submit(new Callable<APIGoodsRecommendResponse>() {
            @Override
            public APIGoodsRecommendResponse call() throws Exception{
                return indexService.getGoodsRecommend(apiGoodsRecommendRequest);
            }
        });
    }

高并发下选取什么样的线程池会比较合理(补充)

高并发,低耗时

建议少线程,只要满足并发即可;例如并发100,线程池可能设置为10就可以。如果线程太多,有可能出现线程切换和管理的时间,大于任务执行的时间,那效率就低了。

低并发,高耗时

建议多线程,保证有空闲线程,接受新的任务;例如并发10,线程池可能就要设置为20;

高并发,高耗时

要分析任务类型,增加排队,加大线程数

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值