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


    controller是线程不安全的,因为controller使用的是单例模式,不同的线程会对数据进行共享,导致数据混乱,没有实现我们想要的结果,除非定义的是常量,那就没有关系.

    因为设计成单例模式的话,就不需要处理太多的gc,性能就可能得到提高

    @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;
        }
    }

    依次调用test1test2方法

    测试结果:发现结果是在test1的结果下进行叠加的

    1
    2

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

    方式一:使用多例模式

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

    @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进行数据的处理

    @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());
        }
    }

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

    1
    2
  • 相关阅读:
    Java学习笔记
    Winform中ListView设置了ColumnHeader不显示问题
    GitHub私有仓库为他人授权
    (转)一步一步教你如何在GitHub上上传自己的项目
    【转】C#中的Explicit和Implicit
    C#对象深表复制方法
    mongodb 设置 ssl
    zabbix 4.0.1部署
    redis编译安装
    VMware网络连接模式——桥接模式、NAT模式以及仅主机模式的介绍和区别
  • 原文地址:https://www.cnblogs.com/yifanSJ/p/16335082.html
Copyright © 2020-2023  润新知