一、对象锁
这种情况不同的对象之间是可以并发的。
synchronized修饰静态方法。
(略)
synchronized修饰代码块。
synchronized (SynchronizedUsage.class){
print();
}
二、类锁
这种情况下不同的对象是不能并发的,但是不同的类之间可以进行并发。
synchronized修饰实例方法。
(略)
synchronized修饰代码块。
synchronized (this) {
print();
}
Object obj = new Object();
synchronized (obj) {
System.out.println("锁的是object对象");
print();
}
三、String变量锁
String.intern()将所有的相同的字符串常量指向了同一个地址:
在jdk1.6中,将此String对象添加到常量池中,然后返回这个String对象的引用(此时引用的串在常量池)。
在jdk1.7中,放入一个引用,指向堆中的String对象的地址,返回这个引用地址(此时引用的串在堆)。
public void test (String riskNo) {
synchronized (riskNo.intern()) {
print();
}
}
注意:
不推荐使用字符串和基本类型的包装类(例如:Integer)作为锁对象,这是因为字符串对象和基本类型的包装对象会有缓存的问题。字符串有字符串常量池,整数有小整数池。因此在使用这些对象的时候他们可能最终都指向同一个对象,因为指向的都是同一个对象,线程获得锁对象的难度就会增加,程序的并发度就会降低。
例如:"HELLO WORLD"字符串在内存当中是同一个对象,是存储在字符串常量池中的对象。Integer.valueOf(1)也同样,Java当中如果整数数据在[-128, 127]之间的话使用的是小整数池当中的对象,使用的也是同一个对象,这样可以减少频繁的内存申请和回收,对内存更加友好。
########## 轻量锁、进程锁后面有时间再研究 ##########
参考:
synchronized块使用string作为锁遇到的问题以及代码原理_技术王老五的博客-CSDN博客_string synchronized

3136

被折叠的 条评论
为什么被折叠?



