synchronize 对 String 加锁
- String 直接赋值 是存储在JVM的常量池中(常量池在方法区中,JDK1.6及之前,方法区在JVM中,之后方法区在内存中),当字符串相同时直接在常量池中取,加锁字符串相同可能会导致加锁对象为同一个。
- 一般都使用新建对象给synchronize 用于上锁(new Object() )
- 对静态方法上锁即是对拥有该方法的 class 上锁
锁对象的改变
- 当锁对象发生改变,锁即不会是同一个。(对String s = “123” 加锁,方法内改变s=“456”,此时锁则不是同一个)
- 给对象加锁,对象的属性发生改变对象并未方式改变,此时锁是同一个
class Service7 {
private String lock = "123";
public void testMethod() {
synchronized (lock) {
try {
System.out.println(Thread.currentThread().getName() + ":begin!");
Thread.sleep(500);
lock = "456";
Thread.sleep(2000);
System.out.println(Thread.currentThread().getName() + ":end!");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class StudyThreads7给字符串对象加锁 {
public static void main(String[] args) throws InterruptedException {
Service7 service7 = new Service7();
Thread threadA = new Thread() {
@Override
public void run() {
service7.testMethod();
}
};
Thread threadB = new Thread() {
@Override
public void run() {
service7.testMethod();
}
};
threadA.setName("A");
threadB.setName("B");
threadA.start();
Thread.sleep(600);
threadB.start();
}
}
给内部静态类加锁
- 内部静态类中的方法加锁与正常类相同,锁不一样代码不同步
- 对内部静态类上锁,则其他方法只能以同步方法访问该类的同步方法