V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
zhao1014
V2EX  ›  Java

引用类型作为方法形参会产生线程安全问题吗?

  •  1
     
  •   zhao1014 · 2020-12-22 19:39:51 +08:00 · 2247 次点击
    这是一个创建于 1439 天前的主题,其中的信息可能已经有所发展或是发生改变。

    书中说不会产生

    可是线程持有引用的副本,通过引用副本操作对象,应该是存在多线程同时操作同一个对象的情况啊,为什么不会有线程安全问题呢?

    第 1 条附言  ·  2020-12-22 20:48:13 +08:00
    谢谢大佬们!问题已经解决了。

    另外,如果是以面试为目的学习多线程,是不是“选择性”的学会更好?
    因为接触的项目不多,书中的实战部分有点难以吸收,我是不是应该直接学习重点理论(其实就是八股文啦)?
    11 条回复    2020-12-23 14:16:30 +08:00
    Jooooooooo
        1
    Jooooooooo  
       2020-12-22 19:45:43 +08:00
    具体什么问题?
    zhao1014
        2
    zhao1014  
    OP
       2020-12-22 20:07:33 +08:00
    @Jooooooooo
    类似于这样?我不知道我举得这个例子对不对,抱歉。

    书中原文是这样的:“对于局部变量(包括形式参数和方法体内定义的变量),由于不同的线程各自访问的是各自的那一份局部变量,因此局部变量的使用不会导致竞态!”

    当时看到就有点疑惑,如果是引用类型,那不同线程操作的还是同一个对象吧。。

    另外,PC 端怎么没有 Append 了,好奇怪。

    public class Demo {

    static class Number {
    int count = 1;
    }

    public static void add(Number number) {
    number.count += 1;
    }

    public static void main(String[] args) {
    Number number = new Number();

    for (int i = 0; i < 100; i++) {
    new Thread() {
    @Override
    public void run() {
    add(number);
    }
    }.start();
    }
    //结果不为 100
    System.out.println(number.count);
    }
    }
    zhao1014
        3
    zhao1014  
    OP
       2020-12-22 20:14:45 +08:00
    原文的意思应该是:“即使对局部变量的操作是非原子性的,也不会导致线程安全问题”
    kera0a
        4
    kera0a  
       2020-12-22 20:27:52 +08:00 via iPhone
    指针指向的那个对象,如果多个线程去修改会有线程安全问题。
    但是你书里说的,局部变量没有

    你方法内,用了一个变量存了这个对象的指针,你对这个变量进行操作是没问题的,你对这个变量里的值所指向的对象进行操作是有问题的
    Zhuzhuchenyan
        5
    Zhuzhuchenyan  
       2020-12-22 20:31:38 +08:00
    1. 即使正确执行预期输出应该是 101
    2. 这里应该关注 += 操作是否是原子的
    3. System.out.println 的调用时机在此处并不保证在所有 Thread 都完成之后
    340244120w
        6
    340244120w  
       2020-12-22 20:33:24 +08:00 via iPhone
    形参本身就存一个引用,你对他的操作仅有改变其引用。比如形参一开始引用的 a,你方法里可以把他改成引用对象 b 。

    而你理解的对象内部改变,是对实参的操作。
    zhao1014
        7
    zhao1014  
    OP
       2020-12-22 20:34:51 +08:00
    @kera0a 懂了,谢谢大佬
    zhao1014
        8
    zhao1014  
    OP
       2020-12-22 20:39:24 +08:00
    @Zhuzhuchenyan 确实是 101,我写错了(狗头); println 这里确实没注意,谢谢提醒;
    @340244120w 看来我对形参和实参的概念理解的有问题,听你说的瞬间就明白了,感谢!
    Takamine
        9
    Takamine  
       2020-12-23 00:25:15 +08:00 via Android
    这个也让我想到了 Java 是值传递的原因。
    catcn
        10
    catcn  
       2020-12-23 08:29:08 +08:00
    请把你二楼贴的代码敲上 20 遍
    SkyLine7
        11
    SkyLine7  
       2020-12-23 14:16:30 +08:00
    栈封闭
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2195 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 01:10 · PVG 09:10 · LAX 17:10 · JFK 20:10
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.