java 字符串 锁
时间: 2024-12-28 08:27:15 浏览: 5
### Java 字符串加锁机制
在 Java 中,字符串可以用作同步锁对象。当多个线程尝试访问共享资源时,可以通过 `synchronized` 块或方法来控制并发访问。使用字符串作为锁对象需要注意一些特定的行为和潜在的风险。
#### 实现方式
为了确保同一内容的字符串能够提供相同的锁对象,通常会使用 `String.intern()` 方法。该方法返回字符串池中的规范表示形式,如果存在相同的内容,则不会创建新的字符串实例[^2]。
```java
public class StringLockExample {
private static final String LOCK_STRING = "lock".intern();
public void safeMethod() {
synchronized (LOCK_STRING) {
System.out.println(Thread.currentThread().getName() + " acquired the lock");
try {
Thread.sleep(1000); // Simulate work being done
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
System.out.println(Thread.currentThread().getName() + " released the lock");
}
}
public static void main(String[] args) throws InterruptedException, BrokenBarrierException {
StringLockExample example = new StringLockExample();
Runnable task = () -> example.safeMethod();
Thread threadA = new Thread(task, "Thread-A");
Thread threadB = new Thread(task, "Thread-B");
threadA.start();
threadB.start();
threadA.join();
threadB.join();
}
}
```
这段代码展示了如何利用 `"lock"` 的内部化版本作为一个全局唯一的锁对象,在两个不同的线程之间实现互斥访问[^3]。
#### 注意事项
- **性能影响**:频繁调用 `String.intern()` 可能会对应用程序造成显著的性能开销,因为这涉及到对 JVM 内部字符串表的操作。
- **内存泄漏风险**:一旦某个字符串被加入到永久代/元空间(取决于JVM版本),它就不会轻易消失,除非对应的类加载器卸载。因此不当使用可能导致内存泄露问题[^4]。
- **不可预测性**:由于编译期优化等原因,即使源码中看起来完全一样的字符串也可能不是同一个对象引用,特别是在跨不同类文件的情况下。所以最好显式地调用 `intern()` 来确保一致性[^1]。
阅读全文