String str="abc" 一定会进入到字符串常量池吗?
如果一定会,为什么我对 str 加锁,锁并没有用。
1
Yimkong 2021-07-08 17:22:14 +08:00 via iPhone
锁是加给对象的,你这个每次加锁都是都会锁一个新的 String 对象。
String str=new String("abc"),锁这个就行 |
2
huang119412 2021-07-08 17:26:22 +08:00
字符串字面量一定进常量池,常量池的字符串不一定不会被回收,synchronized 锁住的对象,当然可以锁住字符串常量对象
|
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(); } 其中一个线程会被阻塞,明显就是锁的是同一个对象,所以会进 字符串常量池 |
4
lululau 2021-07-08 17:30:45 +08:00
都在背面试题吗😂
|
5
3dwelcome 2021-07-08 18:23:19 +08:00 1
java 判断是不是一个对象,直接相等就可以了,都不用上锁。
如果进字符串常量池,就会相等。 |
6
aragakiyuii 2021-07-08 20:25:59 +08:00
|
7
OctopusGO 2021-07-09 10:37:05 +08:00
是的,字面量都会进
|
8
kikione OP @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"; } |
9
MrGoooo 2021-07-09 16:07:38 +08:00
@kikione 请求的数据过来时是以 byte[]格式过来的,怎么将 byte[]转成 String 呢?肯定是调用了 new String(byte[]),所以就算每次传过来的 id 相同,也无法锁住,因为调用了 new String(),导致对象不同.
|
12
kikione OP @zj1403762235 谢谢大佬,byte[] 给了我思路,谢谢
|
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.... 所以。。。。 |
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 |