package demo8;
/**
* @author xianyu
* @version 1.0
* @date 2020/4/20 14:30
* 单例模式: 懒汉式单例模式
*/
public class singleInstance1 {
public static void main(String[] args) {
for (int i = 0; i < 1000; i++) {
Thread t = new Thread(()->{
Teacher.getInstance();
});
t.start();
}
}
}
class Teacher{
// 1. 私有化构造器
private Teacher(){
System.out.println("**********调用构造器*********");
}
// 2. 提供一个私有的静态的该类的对象, 声明时未直接实例化
private static Teacher instance;
// 3. 提供一个静态的获取该类对象的方法,但是对于多线程有问题
// 第一种解决方法:synchronized 同步方法
// public static synchronized Teacher getInstance(){
// if(instance == null){
// instance = new Teacher(); // 懒汉式,等调用时才实例化对象
// }
// return instance;
// }
///第二种解决方法,同步代码块
/* obj 称为同步监视器,也就是锁,
原理是:当线程开始执行同步代码块前,必须先获得对同步代码块的锁定。
并且任何时刻只能有一个线程可以获得对同步监视器的锁定,
当同步代码块执行完成后,该线程会释放对该同步监视器的锁定。
其中的锁,在非静态方法中可为this,
在静态方法中为当前类本身(例如单例模式的懒汉式:singleInstance1.class)。*/
public static Teacher getInstance(){
// 二次判断提高效率
// 这样的话就不用每次都执行同步代码块,只需第一次执行的时候比较占资源,
// 以后的话就和之前的一样了
if(instance == null){
synchronized (singleInstance1.class){
if(instance == null){
instance = new Teacher(); // 懒汉式,等调用时才实例化对象
}
}
}
return instance;
}
}