/**
* 懒汉式的单例模式: 不是线程安全的
* 优点: 在使用的时候才会初始化,可以节省资源
*/
public class SignalLazy {
// 将默认的构造器设置为private类型的
private SignalLazy() {
}
// 静态的单例对象
private static SignalLazy instance;
//静态的获取单例的对象,其中有一个判断,如果没有初始化,那么就创建
public static SignalLazy getInstance() {
// 如果instance没有被初始化,那么就创建即可,这个是保证了单例,但是并不是线程安全的
if (instance == null) {
System.out.println("this is SignalLazy");
instance = new SignalLazy(); // 创建一 个对象
}
return instance; // 返回这个对象
}
}
public class MainTest {
public static void main(String[] args) {
new Thread(new Runnable() {
@Override
public void run() {
//创建实例,并且输出其中的地址,如果地址相同, 那么就是同一个实例
System.out.println("this is"+ SignalLazy.getInstance());
}
}).start();
//主线程也是创建输出其中的地址,运行可以看出这两个地址是不一样的
System.out.println("this is"+SignalLazy.getInstance());
}
}
public synchronized static SignalLazy getInstance() {
// 如果instance没有被初始化,那么就创建即可,这个是保证了单例,但是并不是线程安全的
if (instance == null) {
System.out.println("this is SignalLazy");
instance = new SignalLazy(); // 创建一个对象
}
return instance; // 返回这个对象
}
public class SignalTonDoubleCheck {
private volatile static SignalTonDoubleCheck instance = null;
private SignalTonDoubleCheck() {
}; // 将默认的构造方法设置私有
public static SignalTonDoubleCheck getInstance() {
if (instance == null) {
synchronized (SignalTonDoubleCheck.class) {
if (instance == null) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 这个new 并不是原子操作,因此当多线程进行到这里需要及时刷新这个值,因此要设置为voliate
instance = new SignalTonDoubleCheck();
}
}
}
return instance;
}
}
public class SignalTonInnerHolder {
//私有构造函数
private SignalTonInnerHolder() {
}
/*
* 匿名内部类,其中利用了静态成员变量在类加载的时候初始化,并且只加载一次,因此保证了单例
*/
private static class InnerHolder {
private static SignalTonInnerHolder instance = new SignalTonInnerHolder();
}
public static SignalTonInnerHolder getInstance() {
return InnerHolder.instance; //加载类
}
}
/*
* 饿汉式:线程安全
*
*/
public class SignalHungry {
private SignalHungry() {
}
// 静态变量只有在类加载的时候初始化一次,因此这个是线程安全的
private static SignalHungry instance = new SignalHungry();
public static SignalHungry getInstance() {
return instance;
}
}
public class MainTest {
public static void main(String[] args) {
new Thread(new Runnable() {
@Override
public void run() {
//创建实例,并且输出其中的地址,如果地址相同, 那么就是同一个实例
System.out.println("this is"+ SignalHungry.getInstance());
}
}).start();
//主线程也是创建输出其中的地址,运行可以看出这两个地址是不一样的
System.out.println("this is"+SignalHungry.getInstance());
}
}