当前位置: 首页 > 知识库问答 >
问题:

java 的多线程问题 ?

叶声
2024-01-05

如图所示, 位置 2 和位置3 为什么可以访问 位置1 (也就是主线程)的 point 局部变量 ?
毕竟 位置 2 和位置3 是另外两个线程啊 !!

当我加上 第10行代码后,thread1 和 thead2 中都不能访问主线程中的point 了。我知道这是内部类的“事实最终变量” 的限制。

如下图所示,就是我不理解的地方。(在 “栈内存” 层面)

我的猜测:之所以 thread1 和 tread2 这两个新的线程并没有初始化 point 这个变量 但是还能使用的原因是因为 Runnable 的两个实现类 内部都各自 生成了一个 point 实例变量 ? (虽然书上的解释是针对局部内部类,针对外面的方法执行完毕局部变量就不复存在的原因, 但是我不知道 多线程 能不能也可以同样这样解释)。

共有5个答案

秦涵映
2024-01-05

我觉得这不算栈封闭,栈封闭限于对象不能逸出。比如这样。适用于基础数据类型

class User(val name: String){    val c:Int = 0    fun demo(){        Thread{            val b = c            println(b)        }    }}

即c在怎么改变,也无法对b造成影响。但如果是一个对象。显然结论不成立。第一个回答者的测试在我这里没通过,如果加上thread.join() 就会发现,其实是能够修改,看到之后我真以为不能修改,所以去做了测试。

所以结论就应该是普通的堆调用。堆内存是共享的,所以不需要什么初始化,哪个线程都能使用。至于为什么是final,我觉得可能是为了防止在线程里面随意赋值,导致变量在其他线程里的浅拷贝对象出现错乱。

最后,如果真的对多线程有兴趣,还是推荐《java并发编程实践》 在并发这方面。没有哪本书比这本书更加权威。里面也有关于栈封闭的解释。

孔鹤龄
2024-01-05

能否访问变量只与变量的作用域有关,跟在哪一个线程无关。

你这里同处于一个块级作用域,当然能访问到了。

至于跨线程访问同一个变量是否会有“线程安全”问题,这是另一个问题,跟“能否访问”是两码事儿,没有一点儿关系。

伯茂才
2024-01-05

能不能访问跟在哪个线程创建没有什么关系。

你引用的讨论跟是否多线程貌似也没有关系。

司宏伯
2024-01-05

因为对象在堆里
堆是所有线程共享的
所以可以访问

逄边浩
2024-01-05

堆栈封闭:局部变量,无并发问题,每个线程会各自拷贝一份到各自新建的线程中。

只可使用,不可修改该局部变量的值(因为是复制到新新线程中的,所以只能改副本数据,不能改main函数中局部变量的值)

栈封闭是我们编程当中遇到的最多的线程封闭。什么是栈封闭呢?简单的说就是局部变量。多个线程访问一个方法,此方法中的局部变量都会被拷贝一分儿到线程栈中。所以局部变量是不被多个线程所共享的,也就不会出现并发问题。所以能用局部变量就别用全局的变量,全局变量容易引起并发问题。

    public static void main(String[] args) {        t1();    }    public static void t1() {        AtomicReference<User> user = new AtomicReference<>(new User());        user.set(new User("defaultName"));        Runnable runnable = () -> {            user.set(new User("name1"));        };        Thread thread1 = new Thread(runnable);        Thread thread2 = new Thread(()-> user.set(new User("name2")));        thread1.start();        thread2.start();        System.out.println(user);    }

打印结果:
User(name=defaultName)

 类似资料:
  • 1):单线程应用程序只会在用户的CPU上使用1个线程吗?提供更多的线程会使用多个CPU内核吗?如果声明的线程比用户的CPU多,会发生什么?

  • 教程这样说道:“内部调用了this.notifyAll()而不是this.notify(),使用notifyAll()将唤醒所有当前正在this锁等待的线程,而notify()只会唤醒其中一个(具体哪个依赖操作系统,有一定的随机性)。这是因为可能有多个线程正在getTask()方法内部的wait()中等待” 。 我有点疑惑的一句话是 “可能有多个线程正在getTask()方法内部的wait()中等

  • 我有一个应用程序,它有一个ConcurrentHashMap本地存储一个存储在外部服务器上的数据副本。地图每隔几秒钟就会更新一次数据的新副本。 我有一个循环,每隔几秒钟运行一次,它可以访问HashMap并按照值的顺序将元素添加到数组中(实际上它做的事情还多一些,但这并不相关)。我的问题是,如果数据在创建数组的过程中发生了变化,您可能会在不同的地方有重复的键,或者完全省略一些键。 示例: 如您所见,

  • 前言 Java多线程分类中写了21篇多线程的文章,21篇文章的内容很多,个人认为,学习,内容越多、越杂的知识,越需要进行深刻的总结,这样才能记忆深刻,将知识变成自己的。这篇文章主要是对多线程的问题进行总结的,因此罗列了40个多线程的问题。 这些多线程的问题,有些来源于各大网站、有些来源于自己的思考。可能有些问题网上有;可能有些问题对应的答案也有;也可能有些各位网友也都看过。但是本文写作的重心就是所

  • 我有一个很大的json文件,其中包含一个很长的信息列表,我需要在许多子线程中只读该列表。 在java中,我们可以只通过值而不是引用来传递变量,我希望在内存/磁盘使用方面尽可能减少我的程序。 现在我将完整的列表或它的子列表传递给我创建的每个线程。 有没有一种方法可以从所有线程访问相同的列表变量,而不将完整的列表复制到每个线程中? 我需要“只读取”列表 下面是我的程序是如何工作的 1-服务(等待文件创

  • 我找到了关于线程安全的代码,但它没有来自给出示例的人的任何解释。我想知道为什么如果我不在“count”之前设置“synchronized”变量,那么count值将是非原子的(总是=200是期望的结果)。谢谢