synchronized 锁不住 String
时间: 2023-08-26 17:13:05 浏览: 61
实际上,synchronized 是可以锁住 String 对象的。String 是一个不可变类,每次对 String 对象的修改都会创建一个新的 String 对象,但是这并不影响 synchronized 的使用。
当多个线程对同一个 String 对象进行 synchronized 操作时,只有一个线程能够获得锁,其他线程需要等待锁的释放。这是因为 Java 中的字符串常量池(String Pool)的存在。
字符串常量池是 Java 中用于存储字符串字面值的一个区域,它的目的是节省内存。当我们创建一个字符串常量时,如果字符串常量池中已经存在相同内容的字符串,则返回常量池中的引用,而不会创建新的对象。
因此,如果多个线程对同一个字符串字面值进行 synchronized 操作,它们实际上是在操作同一个对象,可以实现互斥访问。例如:
```java
String str = "hello";
synchronized (str) {
// 互斥操作
}
```
然而,如果你使用 new 关键字创建了一个新的 String 对象,那么这个对象就不再是字符串常量池中的对象,而是一个普通的对象。在这种情况下,synchronized 将无法实现对 String 对象的互斥访问。因此,在使用 synchronized 锁住 String 对象时,应该确保使用的是字符串常量或者确保不会创建新的 String 对象。
相关问题
synchronized 锁不住普通对象
实际上,synchronized 是可以锁住普通对象的。当我们使用 synchronized 关键字修饰一个代码块或方法时,它会获取对象的锁来实现线程的同步。
当多个线程对同一个普通对象进行 synchronized 操作时,只有一个线程能够获得该对象的锁,其他线程需要等待锁的释放。在获得锁的线程执行完同步代码块或方法后,会释放锁,其他线程才有机会获得锁并执行相应的同步操作。
例如,我们可以创建一个普通对象,并在多个线程中使用 synchronized 来进行互斥访问:
```java
class MyObject {
public synchronized void myMethod() {
// 互斥操作
}
}
MyObject obj = new MyObject();
// 在多个线程中调用对象的同步方法
Thread t1 = new Thread(() -> {
obj.myMethod();
});
Thread t2 = new Thread(() -> {
obj.myMethod();
});
t1.start();
t2.start();
```
在上述例子中,通过 synchronized 关键字修饰的 myMethod() 方法,确保了在同一时刻只有一个线程能够执行其中的互斥操作。其他线程需要等待锁的释放,才能继续执行。
需要注意的是,synchronized 锁住的是对象本身,而不是代码块或方法。因此,不同的对象实例之间是独立的,它们的锁是相互独立的。只有同一个对象的不同线程之间才会互斥访问。
synchronized锁方法锁不住
这个问题可以回答。synchronized锁方法是可以锁住的,但是如果锁的是非静态方法,那么锁的是对象实例,如果有多个线程同时访问不同的对象实例,那么锁是无效的。如果锁的是静态方法,那么锁的是类对象,可以保证同一时刻只有一个线程访问该方法。