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

String str="abc" 一定会进入到字符串常量池吗?

  •  
  •   kikione · 2021-07-08 16:55:02 +08:00 · 2604 次点击
    这是一个创建于 1228 天前的主题,其中的信息可能已经有所发展或是发生改变。

    String str="abc" 一定会进入到字符串常量池吗?

    如果一定会,为什么我对 str 加锁,锁并没有用。

    17 条回复    2021-07-11 11:49:28 +08:00
    Yimkong
        1
    Yimkong  
       2021-07-08 17:22:14 +08:00 via iPhone
    锁是加给对象的,你这个每次加锁都是都会锁一个新的 String 对象。
    String str=new String("abc"),锁这个就行
    huang119412
        2
    huang119412  
       2021-07-08 17:26:22 +08:00
    字符串字面量一定进常量池,常量池的字符串不一定不会被回收,synchronized 锁住的对象,当然可以锁住字符串常量对象
    Cy1
        3
    Cy1  
       2021-07-08 17:27:49 +08:00   ❤️ 1
    你是怎么加锁的?
    public static void main(String[] args) {
    String lock1 = "abc";
    String lock2 = "abc";
    new Thread(() -> {
    synchronized (lock1) {
    System.out.println("t1");
    try {
    TimeUnit.SECONDS.sleep(5);
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }
    }, "t1").start();
    new Thread(() -> {
    synchronized (lock2) {
    System.out.println("t2");
    try {
    TimeUnit.SECONDS.sleep(5);
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }
    }, "t2").start();
    }
    其中一个线程会被阻塞,明显就是锁的是同一个对象,所以会进 字符串常量池
    lululau
        4
    lululau  
       2021-07-08 17:30:45 +08:00
    都在背面试题吗😂
    3dwelcome
        5
    3dwelcome  
       2021-07-08 18:23:19 +08:00   ❤️ 1
    java 判断是不是一个对象,直接相等就可以了,都不用上锁。

    如果进字符串常量池,就会相等。
    aragakiyuii
        6
    aragakiyuii  
       2021-07-08 20:25:59 +08:00
    OctopusGO
        7
    OctopusGO  
       2021-07-09 10:37:05 +08:00
    是的,字面量都会进
    kikione
        8
    kikione  
    OP
       2021-07-09 15:32:25 +08:00
    @Cy1 你好,这是我的测试代码,在 controller 中

    @GetMapping("/concurrency")
    public String testConcurrency(Integer num,String id) throws InterruptedException {
    synchronized (id){
    log.info(Thread.currentThread().getName()+":拿到锁");
    orderAservice.changePrice(num,id);
    }
    log.info(Thread.currentThread().getName()+":释放锁");

    return "success";
    }
    MrGoooo
        9
    MrGoooo  
       2021-07-09 16:07:38 +08:00
    @kikione 请求的数据过来时是以 byte[]格式过来的,怎么将 byte[]转成 String 呢?肯定是调用了 new String(byte[]),所以就算每次传过来的 id 相同,也无法锁住,因为调用了 new String(),导致对象不同.
    MrGoooo
        10
    MrGoooo  
       2021-07-09 16:09:51 +08:00
    @kikione 你可以试试将每次请求过来的 id 都放在一个 list 里面,然后用"=="比较,肯定是不同的.
    Cy1
        11
    Cy1  
       2021-07-09 16:44:38 +08:00
    @kikione #8 楼已经跟你解释明白了
    kikione
        12
    kikione  
    OP
       2021-07-09 16:44:44 +08:00
    @zj1403762235 谢谢大佬,byte[] 给了我思路,谢谢
    kikione
        13
    kikione  
    OP
       2021-07-09 16:45:32 +08:00
    @Cy1 谢谢,恍然大悟,我再研究一下
    Aruforce
        14
    Aruforce  
       2021-07-09 16:48:39 +08:00
    @kikione 锁的又不是 value,是 reference 的地址也就是 id 具体的地址...而这个 id 地址 每次方法执行都不一样;

    这里的 id 不是 C 的 char * str = "predefinedstr" 语句 里面的 str
    这里的 id 是 C 的 char str [] ="predefinedstr" 的 str....
    所以。。。。
    Cy1
        15
    Cy1  
       2021-07-09 17:13:14 +08:00
    @kikione 既然你用 SpringMVC 了,你倒是可以顺便研究一下 SpringMVC 是怎么生成这个 String id 的,以及怎么调用你这个方法的。大概这个顺序
    org.springframework.web.method.support.InvocableHandlerMethod#invokeForRequest
    org.springframework.web.method.support.InvocableHandlerMethod#getMethodArgumentValues
    org.springframework.web.method.support.HandlerMethodArgumentResolverComposite#resolveArgument
    org.springframework.web.method.annotation.AbstractNamedValueMethodArgumentResolver#resolveArgument
    MrGoooo
        16
    MrGoooo  
       2021-07-09 20:06:37 +08:00
    @kikione 刚开始我也有点不知道咋解释,后来想到数据是以字节流传输的,想到字节流转成字符串的过程应该是用了 new String()
    kikione
        17
    kikione  
    OP
       2021-07-11 11:49:28 +08:00
    @Cy1 谢谢!
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   856 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 21:49 · PVG 05:49 · LAX 13:49 · JFK 16:49
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.