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

2021-07-08 16:55:02 +08:00
 kikione

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

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

2645 次点击
所在节点    程序员
17 条回复
Yimkong
2021-07-08 17:22:14 +08:00
锁是加给对象的,你这个每次加锁都是都会锁一个新的 String 对象。
String str=new String("abc"),锁这个就行
huang119412
2021-07-08 17:26:22 +08:00
字符串字面量一定进常量池,常量池的字符串不一定不会被回收,synchronized 锁住的对象,当然可以锁住字符串常量对象
Cy1
2021-07-08 17:27:49 +08:00
你是怎么加锁的?
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
2021-07-08 17:30:45 +08:00
都在背面试题吗😂
3dwelcome
2021-07-08 18:23:19 +08:00
java 判断是不是一个对象,直接相等就可以了,都不用上锁。

如果进字符串常量池,就会相等。
aragakiyuii
2021-07-08 20:25:59 +08:00
OctopusGO
2021-07-09 10:37:05 +08:00
是的,字面量都会进
kikione
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
2021-07-09 16:07:38 +08:00
@kikione 请求的数据过来时是以 byte[]格式过来的,怎么将 byte[]转成 String 呢?肯定是调用了 new String(byte[]),所以就算每次传过来的 id 相同,也无法锁住,因为调用了 new String(),导致对象不同.
MrGoooo
2021-07-09 16:09:51 +08:00
@kikione 你可以试试将每次请求过来的 id 都放在一个 list 里面,然后用"=="比较,肯定是不同的.
Cy1
2021-07-09 16:44:38 +08:00
@kikione #8 楼已经跟你解释明白了
kikione
2021-07-09 16:44:44 +08:00
@zj1403762235 谢谢大佬,byte[] 给了我思路,谢谢
kikione
2021-07-09 16:45:32 +08:00
@Cy1 谢谢,恍然大悟,我再研究一下
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
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
2021-07-09 20:06:37 +08:00
@kikione 刚开始我也有点不知道咋解释,后来想到数据是以字节流传输的,想到字节流转成字符串的过程应该是用了 new String()
kikione
2021-07-11 11:49:28 +08:00
@Cy1 谢谢!

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/788338

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX