给静态方法加同步锁
我们知道利用synchronized关键字可以解决线程安全的问题,synchronized可以加在代码块中,也可以加在同步方法中。synchronized加在方法中的时候等价于:
synchronized(this){
对共享资源进行操作的代码块
}
问题:静态方法的锁加在什么对象上呢?
加锁的时候要传一个Object对象,但是static修饰的方法在加载的时候是没有new出对象的,实际上这个锁是加在当前类的字节码对象上。
单利设计模式有2种:
1.饿汉式
public class Singal{
private static final Singal singal = new Singal();
private Singal(){};
private static Singal getInstance()
{
return singal;
}
}
2.懒汉式
有人觉得上面那种的效率不是很高,于是就出现了下面一种,简称懒汉式
优点是可以实现延迟加载,效率高。
public class Singal {
public static Singal singal = null;
private Singal() {};
private static Singal getInstance() {
if (singal == null) {
singal = new Singal();
}
return singal;
}
}
分析:红色标记的这段代码会出现线程安全问题
当if(singal==null)这段代码执行完后,另外一个线程也抢到了cpu的执行权
并执行完,生成了一个Singal对象。等原线程回过头也会生成一个Singal对象。
这样就生成了2个singal对象了,线程安全问题也就这样产生了。
注:对上面代码进行优化后,就不会出现线程安全问题,但是锁是加在当前类的字节码
对象上的。
public class Singal {
// 懒汉式有延迟加载的功能,但是会出现线程不安全的问题。
public static Singal singal = null;
private Singal() {};
private static Singal getInstance() {
synchronized (Singal.class) {
if (singal == null) {
singal = new Singal();
}
}
return singal;
}
}