1.定义
单例模式:指一个类只有一个实例,且该类能自行创建这个实例的一种模式。例如:Windows中只能打开一个任务管理器,这样可以避免因打开多个任务管理器窗口而造成内存资源的浪费,或出现各个窗口显示的内容不一致。
2.特点
- 只有一个实例对象
- 该单例对象必须有单例类自行创建
- 单例类对外提供一个访问该单例的全局访问点
3.实现
单例模式的实现方式有两种:懒汉模式和饿汉模式
懒汉模式
简介:类加载时没有生成单例,只有第一次调用访问点方法时才会去创建这个单例。
package ink.poesy.design;
/**
* 单例模式
* Singleton(单例)
*/
public class LazySingleton {
//volatile (共享变量):是指可以同时被多个线程访问的变量,共享变量是被存放在堆里面,所有的方法内临时变量都不是共享变量。
//具有synchronized关键字的“可见性”,但是没有synchronized关键字的“并发正确性”,也就是说不保证线程执行的有序性。
//相比于synchronized(synchronized通常称为重量级锁),volatile更轻量级,因为它不会引起线程上下文的切换和调度。
private static volatile LazySingleton lazySingleton = null; //保证lazySingleton在所有线程中同步
private LazySingleton(){} //private 避免类在外部被实例化
public static synchronized LazySingleton getLazySingleton(){
//getLazySingleton方法前加同步
if(lazySingleton == null){
lazySingleton = new LazySingleton();
}
return lazySingleton;
}
}
注意:如果编写的是多线程程序,则不要删除上例代码中的关键字 volatile 和 synchronized,否则将存在线程非安全的问题。如果不删除这两个关键字就能保证线程安全,但是每次访问时都要同步,会影响性能,且消耗更多的资源,这是懒汉式单例的缺点。
饿汉模式
该模式的特点是类一旦加载就创建一个单例,保证在调用 getHugrySigleton方法之前单例已经存在了。
package ink.poesy.design;
/**
* 单例模式:饿汉实现
*/
public class HungrySingleton {
private static final HungrySingleton hugrySigleton = new HungrySingleton();
private HungrySingleton(){}
public static HungrySingleton getHugrySigleton(){
return hugrySigleton;
}
}
4.示例
一夫一妻制度:一个丈夫只能有一个妻子,或一个妻子只能有一个丈夫。懒汉模式实现它
package ink.poesy.design;
import java.util.Date;
/**
* 一夫一妻制度
*/
public class Monogamy {
public static void main(String[] args) {
Wife w1 = Wife.getInstance();
w1.getTime();
Wife w2 = Wife.getInstance();
w2.getTime();
if(w1 == w2){
System.out.println("他们是同一人!");
}
else
{
System.out.println("他们不是同一人!");
}
}
static class Wife{
private static volatile Wife instance = null;
long time ;
private Wife(){
time = new Date().getTime();
System.out.println("结婚~恭喜恭喜");
}
public static synchronized Wife getInstance(){
if(instance == null){
instance = new Wife();
}else{
System.out.println("已经结婚,不能再另外妻子!");
}
return instance;
}
public void getTime(){
System.out.println("结婚日期:"+time);
}
}
}
运行效果
注明:以上内容如有争议、指正,留言给我~