点击上方 Java后端,选择 设为星标
优质文章,及时送达
- 
singleton:单例,默认作用域。
 - 
prototype:原型,每次创建一个新对象。
 - 
request:请求,每次Http请求创建一个新对象,适用于WebApplicationContext环境下。
 - 
session:会话,同一个会话共享一个实例,不同会话使用不用的实例。
 - 
global-session:全局会话,所有会话共享一个实例。
 
spring单例,为什么controller、service和dao确能保证线程安全?
- 
有状态就是有数据存储功能
 - 
无状态就是不会保存数据 controller、service和dao层本身并不是线程安全的,只是如果只是调用里面的方法,而且多线程调用一个实例的方法,会在内存中复制变量,这是自己的线程的工作内存,是安全的。
 
Java虚拟机栈是线程私有的,它的生命周期与线程相同。虚拟机栈描述的是Java方法执行的内存模型:每个方法在执行的同时都会创建一个栈帧用于存储局部变量表、操作数栈、动态链接、方法出口等信息。 
局部变量的固有属性之一就是封闭在执行线程中。它们位于执行线程的栈中,其他线程无法访问这个栈。 
首先问@Controller @Service是不是线程安全的?
@RestController
public class TestController {
    private int var = 0;
    
    @GetMapping(value = "/test_var")
    public String test() {
        System.out.println("普通变量var:" + (++var));
        return "普通变量var:" + var ;
    }
}
普通变量var:1
普通变量var:2
普通变量var:3
@RestController
@Scope(value = "prototype") // 加上@Scope注解,他有2个取值:单例-singleton 多实例-prototype
public class TestController {
    private int var = 0;
    
    @GetMapping(value = "/test_var")
    public String test() {
        System.out.println("普通变量var:" + (++var));
        return "普通变量var:" + var ;
    }
}
普通变量var:1
普通变量var:1
普通变量var:1
@RestController
@Scope(value = "prototype") // 加上@Scope注解,他有2个取值:单例-singleton 多实例-prototype
public class TestController {
    private int var = 0;
    private static int staticVar = 0;
    @GetMapping(value = "/test_var")
    public String test() {
        System.out.println("普通变量var:" + (++var)+ "---静态变量staticVar:" + (++staticVar));
        return "普通变量var:" + var + "静态变量staticVar:" + staticVar;
    }
}
普通变量var:1---静态变量staticVar:1
普通变量var:1---静态变量staticVar:2
普通变量var:1---静态变量staticVar:3
@RestController
@Scope(value = "singleton") // prototype singleton
public class TestController {
    private int var = 0; // 定义一个普通变量
    private static int staticVar = 0; // 定义一个静态变量
    @Value("${test-int}")
    private int testInt; // 从配置文件中读取变量
    ThreadLocal<Integer> tl = new ThreadLocal<>(); // 用ThreadLocal来封装变量
    @Autowired
    private User user; // 注入一个对象来封装变量
    @GetMapping(value = "/test_var")
    public String test() {
        tl.set(1);
        System.out.println("先取一下user对象中的值:"+user.getAge()+"===再取一下hashCode:"+user.hashCode());
        user.setAge(1);
        System.out.println("普通变量var:" + (++var) + "===静态变量staticVar:" + (++staticVar) + "===配置变量testInt:" + (++testInt)
                + "===ThreadLocal变量tl:" + tl.get()+"===注入变量user:" + user.getAge());
        return "普通变量var:" + var + ",静态变量staticVar:" + staticVar + ",配置读取变量testInt:" + testInt + ",ThreadLocal变量tl:"
                + tl.get() + "注入变量user:" + user.getAge();
    }
}
@Configuration
public class MyConfig {
    @Bean
    public User user(){
        return new User();
    }
}
先取一下user对象中的值:0===再取一下hashCode:241165852
普通变量var:1===静态变量staticVar:1===配置变量testInt:1===ThreadLocal变量tl:1===注入变量user:1
先取一下user对象中的值:1===再取一下hashCode:241165852
普通变量var:2===静态变量staticVar:2===配置变量testInt:2===ThreadLocal变量tl:1===注入变量user:1
先取一下user对象中的值:1===再取一下hashCode:241165852
普通变量var:3===静态变量staticVar:3===配置变量testInt:3===ThreadLocal变量tl:1===注入变量user:1
先取一下user对象中的值:0===再取一下hashCode:853315860
普通变量var:1===静态变量staticVar:1===配置变量testInt:1===ThreadLocal变量tl:1===注入变量user:1
先取一下user对象中的值:1===再取一下hashCode:853315860
普通变量var:1===静态变量staticVar:2===配置变量testInt:1===ThreadLocal变量tl:1===注入变量user:1
先取一下user对象中的值:1===再取一下hashCode:853315860
普通变量var:1===静态变量staticVar:3===配置变量testInt:1===ThreadLocal变量tl:1===注入变量user:1
public class MyConfig {
    @Bean
    @Scope(value = "prototype")
    public User user(){
        return new User();
    } 
}
先取一下user对象中的值:0===再取一下hashCode:1612967699
普通变量var:1===静态变量staticVar:1===配置变量testInt:1===ThreadLocal变量tl:1===注入变量user:1
先取一下user对象中的值:0===再取一下hashCode:985418837
普通变量var:1===静态变量staticVar:2===配置变量testInt:1===ThreadLocal变量tl:1===注入变量user:1
先取一下user对象中的值:0===再取一下hashCode:1958952789
普通变量var:1===静态变量staticVar:3===配置变量testInt:1===ThreadLocal变量tl:1===注入变量user:1
作者:myseries
cnblogs.com/myseries/p/11729800.html
最近整理一份面试资料《Java技术栈学习手册》,覆盖了Java技术、面试题精选、Spring全家桶、Nginx、SSM、微服务、数据库、数据结构、架构等等。 获取方式:点“ 在看,关注公众号 Java后端 并回复 777 领取,更多内容陆续奉上。 推 荐 阅 读 1. 把 Spring Cloud 给拆了!你知道每个组件的原理吗? 2. 给你的 MyBatis-Plus 装上批量插入的翅膀 3. 36 张图梳理 Intellij IDEA 常用设置 4. 图解 SQL 5. 讨论:Service层需要接口吗?
喜欢文章,点个 在看 ![]()
    
    
    
 
     
     
     
    
    
     
本文分享自微信公众号 - Java后端(web_resource)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。
相关文章
暂无评论...

