一. 概念
单例(Singleton):指一个类只有一个实例,且该类能自行创建这个实例的一种模式。
二. 特点
2.1 单例类只有一个实例对象
2.2 该单例对象必须由一个单例类自行创建
2.3 单例类对外提供一个访问该类单例的全局访问点
三. 应用
在有些系统中,为了节省资源、保证数据内同的一致性,对某些类要求只能创建一个实例,这就是单例模式。
四. 单例模式创建的方式分类
4.1 懒汉模式
该模式的特点是类加载时没有生成单例,只有当第一次调用 getlnstance 方法时才去创建这个单例。代码如下:
public class LazySingleton
{
private static volatile LazySingleton instance=null; //保证 instance 在所有线程中同步
private LazySingleton(){} //private 避免类在外部被实例化
public static synchronized LazySingleton getInstance()
{
//getInstance 方法前加同步
if(instance==null)
{
instance=new LazySingleton();
}
return instance;
}
}
4.2 饿汉模式
该模式的特点是类一旦加载就创建一个单例,保证在调用 getInstance 方法之前单例已经存在了。
public class HungrySingleton
{
private static final HungrySingleton instance=new HungrySingleton();
private HungrySingleton(){}
public static HungrySingleton getInstance()
{
return instance;
}
}
五. 实例测试
5.1 懒汉模式
package com.hjb.singleton.pojo;
/**
* @DESC 设计模式-单例模式-之懒汉模式创建
* @author HJB
* @date 2020年4月19日 上午10:56:52
*/
public class PresidentPOJO {
public static volatile PresidentPOJO president = init();
private String name;
private Integer age;
private static PresidentPOJO init() {
if (president == null) {
president = new PresidentPOJO();
}
return president;
}
private PresidentPOJO() {
System.out.println("实例化一个总统对象");
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "President [name=" + name + ", age=" + age + "]";
}
}
package com.hjb.singleton.start;
import com.hjb.singleton.pojo.PresidentPOJO;
/**
* @DESC 用懒汉式单例模式模拟产生美国当今总统对象
* @author HJB
* @date 2020年4月19日 上午10:54:52
*/
public class SingletonLazy {
public static void main(String[] args) {
PresidentPOJO president1 = PresidentPOJO.president;
president1.setName("奥巴马");
president1.setAge(55);
PresidentPOJO president2 = PresidentPOJO.president;
president2.setName("特朗普");
president2.setAge(65);
System.out.println(president1);//President [name=特朗普, age=65]
System.out.println(president2);//President [name=特朗普, age=65]
}
}
5.2 饿汉模式
package com.hjb.singleton.pojo;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JPanel;
/**
* @DESC 设计模式-单例模式-饿汉模式
* @author HJB
* @date 2020年4月19日 上午11:11:35
*/
public class CiweiPOJO extends JPanel{
private static final long serialVersionUID = 1L;
public static CiweiPOJO ciwei = new CiweiPOJO();
private CiweiPOJO() {
JLabel jl = new JLabel(new ImageIcon("D:\\photos\\ciwei.jpg"));
this.add(jl);
}
public static CiweiPOJO instance() {
return ciwei;
}
}
package com.hjb.singleton.start;
import java.awt.Container;
import java.awt.GridLayout;
import javax.swing.JFrame;
import com.hjb.singleton.pojo.CiweiPOJO;
/**
* @DESC 用饿汉式单例模式模拟产生刺猬对象。
* @author HJB
* @date 2020年4月19日 上午11:23:25
*/
public class SingletonEager {
public static void main(String[] args) {
JFrame jf=new JFrame("饿汉单例模式测试");
jf.setLayout(new GridLayout(1,2));
Container contentPane=jf.getContentPane();
CiweiPOJO obj1=CiweiPOJO.instance();
contentPane.add(obj1);
CiweiPOJO obj2=CiweiPOJO.instance();
contentPane.add(obj2);
if(obj1==obj2)
{
System.out.println("他们是同一人!");
}
else
{
System.out.println("他们不是同一人!");
}
jf.pack();
jf.setVisible(true);
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}