单例设计模式 Singleton
只有一个实例对象
public class TestSingleton {
public static void main(String[] args) {
MySingleton mySingleton = MySingleton.getMySingleton();
System.out.println(mySingleton);
MySingleton singleton = MySingleton.getMySingleton();
System.out.println(singleton);
}
}
//创建单例设计的类
class MySingleton{
private MySingleton(){}
private static MySingleton mySingleton=new MySingleton();
public static MySingleton getMySingleton(){
return mySingleton;
}
}
饿汉式
//饿汉式,线程安全但是浪费内存
class MySingleton {
private MySingleton() {
}
private static MySingleton mySingleton = new MySingleton();
public static MySingleton getMySingleton() {
return mySingleton;
}
}
懒汉式
//懒汉式,线程不安全需要加锁
class LasySingleton {
private LasySingleton() {
}
private static LasySingleton lasySingleton;
public static LasySingleton getInstance() {
if (lasySingleton == null) {
lasySingleton = new LasySingleton();
}
return lasySingleton;
}
}
双检锁
//双检锁,整合了饿汉式和懒汉式的优缺点
class DoubleChecked{
//双检锁 变量需要用volatile修饰
//原因:1.实例化对象分为三个步骤
// 2.内存有缓存,多个线程可能读到缓存的对象=null,创建多个实例对象
/**
* 1.分配内存空间
* 2.初始化对象
* 3.将对象指向刚分配的内存空间
* 而有些编译器为了性能会重新排序2,3步骤,当将对象指向刚分配的内存空间时
* 还没有初始化对象
* 加入修饰词volatile 禁止重排序,所有的写(write)都在读(read)之前
* 参考:https://www.cnblogs.com/xz816111/p/8470048.html
*/
private static volatile DoubleChecked doubleChecked;
private DoubleChecked(){}
private static DoubleChecked getInstance(){
if (doubleChecked==null){
synchronized (DoubleChecked.class){
if (doubleChecked==null){
doubleChecked=new DoubleChecked();
}
}
}
return doubleChecked;
}
}