当前位置: 首页 > news >正文

线程对局部变量以及对只能通过当前线程的局部变量才能访问到的对象进行的操作总是线程安全的

基本定义

局部变量 是指在函数或代码块内部定义的变量,其作用范围仅限于定义它的函数或代码块内部
线程安全 是指多个线程访问共享资源时,不会破坏资源的完整性

示例1

    public void example() {
        Object obj = new Object();
    }

上述创建对象的代码中,obj就是变量,如果在方法中创建这个对象那么obj就属于局部变量,obj和右边的Object()是两个东西,obj是变量,由于创建的是引用类型,所以obj存储在栈中的是地址值,这个内存地址指向堆中的Object()实例,又由于创建的地方在方法内,所以其他线程无法共享obj变量,每个进入该方法的线程都会重复创建只属于自己的Object()对象。
结论

  1. obj变量属于局部变量,无法被其他线程修改
  2. obj引用的new Object()对象属于只能通过当前线程的局部变量才能访问到的对象

所以上述代码总是线程安全的

示例2

@Slf4j
public class Test {

    public List<Integer> list = null;

    public void k1(List<Integer> argList) {
        log.info("k1接收到的list哈希{}",argList.hashCode());
        argList.forEach(System.out::println);
    }

    public static void main(String[] args) throws InterruptedException {
        Test test = new Test();
        test.list = new Vector<>(); // 集合1
        test.list.add(998);
        test.list.add(999);
        log.info("调用k1前的list哈希{}",test.list.hashCode());
        new Thread(() -> {
            test.k1(test.list);
        }).start();
        test.list = new Vector<>(); // 集合2
        test.list.add(1);
        test.list.add(2);
        log.info("调用k1后的list哈希{}",test.list.hashCode());
    }
}

如上代码所示,k1方法中的参数argList也是局部变量,但是在main方法中调用k1的动作是由其他线程完成的,所以这里k1实际接收到的参数就是不确定的,不能确定新启动的线程进入k1方法时传入的集合是1还是2,不过可以确定的是,一旦进入k1方法,不管实际传入的集合是1还是2,这个集合就已经确定了(也就是argList变量持有的引用地址),即使后续main方法中再怎么修改test.list的引用也没关系,因为k1方法中的局部变量argList已经持有了进入该方法时传入的集合的引用地址。
重点提示
虽然argList变量是线程安全的(argList变量会一直指向传入该方法的实例的内存地址,对于argList变量的修改也只能在k1方法中实现),但是对于argList变量指向的实例内容则不做保证,因为在k1方法执行过程中argList引用的集合可能被其他线程添加或删除元素,虽然本例中使用的是线程安全的Vector,但是大部分业务代码可能都是使用ArrayList集合(非线程安全集合),所以还是需要注意。
结论:

  1. k1方法的argList变量属于局部变量
  2. argList变量引用的List不属于【只能通过当前线程的局部变量才能访问到的对象】,所以对于引用的List来说,我们需要自己保证线程安全

相关文章:

  • Android 中两个 APK 之间切换的几中方法
  • 数据结构:ArrayList与顺序表
  • Nginx RTMP 服务器开发设计与实现
  • 极速全场景 MPP数据库starrocks介绍
  • sqlmap 源码阅读与流程分析
  • Kafka 的延迟队列、死信队列和重试队列
  • 蓝桥杯经典题解:班级活动分组问题的深度解析与优化实现
  • 【C++ 真题】P1109 学生分组
  • [Vue2]v-bind操作class
  • 5.3 MVVM模型
  • SSH 公私钥对使用指南
  • Flutter项目之页面实现以及路由fluro
  • (每日一道算法题)最长回文子串
  • 15三数之和解题记录
  • 使用 Flask 框架添加多个AI模型的API进行对话
  • 【读论文】——基于高光谱的玉米籽粒黄曲霉侵染方法研究
  • codis分布式集群
  • 【LeetCode 热题 100】解答汇总
  • 【NLP 50、损失函数 KL散度】
  • 第2.5节 iOS 覆盖率数据的采集
  • 怎样下载做网站的软件/产品推广活动策划方案
  • 没有排名的网站怎么做/by72777最新域名查询
  • 做电影网站如何寻找资源/免费注册个人网站
  • 表格如何给网站做链接/如何推广好一个产品
  • 建网站和建网页的区别/软文广告经典案例800字
  • 用wordpress还是php/seo招聘要求