【java并发系列】Controller是线程安全吗_ 安全方式如何

大家好,我是walker
一个从文科自学转行的程序员~
爱好编程,偶尔写写编程文章和生活
欢迎关注公众号【I am Walker】,回复“电子书”,就可以获得200多本编程相关电子书哈~
我的gitee:https://gitee.com/shen-chuhao/walker.git 里面很多技术案例!

controller是线程不安全的,因为controller使用的是单例模式,不同的线程会对数据进行共享,导致数据混乱,没有实现我们想要的结果,除非定义的是常量,那就没有关系.
因为设计成单例模式的话,就不需要处理太多的gc,性能就可能得到提高

测试案例

package com.walker.springbootdemo.controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
* author:walker
* time: 2022/3/20
* description:  测试controller是否安全
*/
@RestController
@RequestMapping("notSafe")
public class ControllerNotSafeTest {
    //1、定义num,判断不同线程访问的时候,num的返回结果是否一致
    private Integer num=0;

    /**
    * 2、定义两个方法
    */
    @GetMapping("/test1")
    public Integer test1(){
        System.out.println(++num);
        return num;
    }

    @GetMapping("/test2")
    public Integer test2(){
        System.out.println(++num);
        return num;
    }




}

依次调用test1和test2方法
测试结果:发现结果是在test1的结果下进行叠加的

1
2

那么如果想让controller变成线程安全,也就是每个线程独享自己的属性,应该怎么处理呢?

方式一:使用多例模式

增加注解:@Scope("prototype")

package com.walker.springbootdemo.controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
* author:walker
* time: 2022/3/20
* description:  测试controller是否安全
*/
@RestController
@RequestMapping("notSafe")
public class ControllerNotSafeTest {
    //1、定义num,判断不同线程访问的时候,num的返回结果是否一致
    private Integer num=0;

    /**
    * 2、定义两个方法
    */
    @GetMapping("/test1")
    public Integer test1(){
        System.out.println(++num);
        return num;
    }

    @GetMapping("/test2")
    public Integer test2(){
        System.out.println(++num);
        return num;
    }
}

方式二:使用threadLocal进行数据的处理

package com.walker.springbootdemo.controller.safe;

import org.springframework.context.annotation.Scope;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
* author:walker
* time: 2022/3/20
* description:  测试controller是否安全
*/
@RestController
//修改为多例模式
@Scope("prototype")
@RequestMapping("threadLocalSafe")
public class ControllerSafeThreadLocalTest {
    //1、定义threadLocal 线程独享
    ThreadLocal<Integer> threadLocal=new ThreadLocal<>();

    /**
    * 2、定义两个方法
    */
    @GetMapping("/test1")
    public void test1(){
        threadLocal.set(1);
        System.out.println(threadLocal.get());
    }

    @GetMapping("/test2")
    public void test2(){
        threadLocal.set(2);
        System.out.println(threadLocal.get());
    }

}

执行结果:test1和test2线程可以操纵自己的threadLocal,从而达到数据隔离

1
2
  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

WalkerShen

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值