synchronized ("XXX".trim().intern()) {//锁内代码}
我在小测试中main跑多个不同线程不同代码下,这个锁是能起效的。
但是IDEA和AI都说这块写法会有问题,
我生产环境是webSocket下用的,比较难测,想问下会不会有问题(没锁住)
synchronized使用问题
- 写回答
- 好问题 0 提建议
- 关注问题
- 邀请回答
-
1条回答 默认 最新
IT论之程序员 2023-06-07 21:39关注使用String对象作为锁对象会有潜在的问题,因为JVM会对字符串进行优化,有可能导致不同的字符串对象共享同一个内存空间。 在你的例子中,如果两个线程调用的字符串是"XXX"和"XXX ",由于trim()和intern()操作,这两个字符串实际上会指向同一个对象,导致锁失效。 所以,使用字符串作为锁对象时,推荐使用如下方式: 1. 使用字符串的hashCode()作为锁: java synchronized ( "XXX".hashCode()) { ... } 2. 使用新的String对象作为锁: java String lockObj = new String("XXX"); synchronized (lockObj) { ... } 3. 不使用字符串,选择其他对象作为锁: java Object lockObj = new Object(); synchronized (lockObj) { ... } 对于你的webSocket示例,我的建议是: 1. 不要直接使用字符串作为锁 2. 可以为每个WebSocket连接生成一个唯一的锁对象,然后所有的同步块针对这个锁对象进行同步。例如: java Object lockObj = new Object(); webSocket.onConnect((session) -> { session.setLockObj(lockObj); //为连接生成锁对象 }); //同步块使用这个锁对象 synchronized (session.getLockObj()) { ... } 3. 也可以使用其他的同步机制,如ReentrantLock来代替synchronized关键字。 总之,不推荐在生产环境直接使用字符串作为锁对象,以免出现同步失效的问题。解决 无用评论 打赏 举报