单例设计模式
所谓单例设计模式,就是采取一定的方法保证在整个的软件系统中,对某个类只能存在一个对象实例。
写一个单例设计模式的一般步骤分3步:
- 私有化构造器
- 定义一个类变量记住类的一个对象
- 设计一个对外的共有方法来获取这个实例对象
Runtime类就是一个典型的单例设计模式
单例模式有8种实现方法
1. 饿汉式(静态常量)
2. 饿汉式(静态代码块)
-
懒汉式(线程不安全)
-
懒汉式(同步方法,线程安全)
-
懒汉式(同步代码块,线程不安全)
**6. 双重检查(线程安全) -
静态内部类
-
枚举**
1、饿汉式(静态常量)
java
class Singleton{
//构造器私有化
private Singleton(){
}
//本类内部创建实例对象 为什么需要static修饰?因为这是类变量
private final static Singleton instance = new Singleton();
//提供一个静态方法,返回实例对象
public static Singleton getInstance(){
return instance;
}
}
2、饿汉式(静态代码块)
java
class Singleton{
//构造器私有化
private Singleton(){
}
private static Singleton instance ;
//在静态代码块中创建实例对象 why? 因为静态代码块只会被执行一次
static {
instance = new Singleton();
}
//提供一个静态方法,返回实例对象
public static Singleton getInstance(){
return instance;
}
}
3、懒汉式(线程不安全)
在调用getInstance()方法的时候才会被创建实例对象
java
class Singleton{
private static Singleton instance;
//构造器私有化
private Singleton(){
}
//提供一个静态的公有方法,当使用到该方法的时候,才去创建instance
//懒汉式
public static Singleton getInstance(){
if (instance == null){
instance = new Singleton();
}
return instance;
}
}
4、懒汉式(同步方法,线程安全)
java
class Singleton{
private static Singleton instance;
//构造器私有化
private Singleton(){
}
//提供一个静态的公有方法,当使用到该方法的时候,才去创建instance
//懒汉式(同步方法)
public static synchronized Singleton getInstance(){
if (instance == null){
instance = new Singleton();
}
return instance;
}
}
5、懒汉式(同步代码块,线程不安全)
java
class Singleton{
private static Singleton instance;
//构造器私有化
private Singleton(){
}
//提供一个静态的公有方法,当使用到该方法的时候,才去创建instance
//懒汉式(同步代码块)
public static Singleton getInstance(){
if (instance == null){
synchronized (Singleton.class){
instance = new Singleton();
}
}
return instance;
}
}
6、双重检查(线程安全)
java
class Singleton{
private static volatile Singleton instance;
//构造器私有化
private Singleton(){
}
//提供一个静态的公有方法,当使用到该方法的时候,才去创建instance
//加入双重检查代码,解决线程安全问题,同时解决懒加载问题
public static Singleton getInstance(){
if (instance == null){
synchronized (Singleton.class){
if (instance == null){
instance = new Singleton();
}
}
}
return instance;
}
}
7、静态内部类
java
class Singleton{
//构造器私有化
private Singleton(){
}
//写一个静态内部类,该类中有一个静态属性Singleton
//1、在Singleton被装载的时候,这个静态内部类不会被装载
//2、当调用getInstance装载SingletonInstance的时候,只会被执行一次
private static class SingletonInstance{
private static final Singleton instance= new Singleton();
}
//提供一个静态的公有方法,直接返回SingletonInstance.INSTANCE
public static synchronized Singleton getInstance(){
return SingletonInstance.instance;
}
}
8、枚举
java
//使用枚举,可以实现单例
enum Singleton{
INSTANCE;
public void sayOK(){
System.out.println("ok~");
}
}
根据上面的描述,写卡码网的购物车案例
https://kamacoder.com/problempage.php?pid=1074
首先创建一个商品类
java
//需要一个商品类
class Spu{
private String spuName;
private int spuNum;
public Spu() {
}
public Spu(String spuName, int spuNum) {
this.spuName = spuName;
this.spuNum = spuNum;
}
public String getSpuName() {
return spuName;
}
public int getSpuNum() {
return spuNum;
}
}
下面的购物车类使用单例模式:
1、饿汉式(静态常量)
java
//使用饿汉式创建一个购物车类
class Cart{
private final List<Spu> spuList;
//私有化构造器
private Cart(){
spuList = new ArrayList<>();
}
//本类内部创建实例对象
private final static Cart instance = new Cart();
//提供一个静态方法,返回实例对象
public static Cart getInstance(){
return instance;
}
public void addSpu(String spuName, int spuNum){
Spu spu = new Spu(spuName,spuNum);
this.spuList.add(spu);
}
public void printSpuList(){
for (Spu spu :
spuList) {
System.out.println(spu.getSpuName()+" "+spu.getSpuNum());
}
}
}
2、饿汉式(静态代码块)
java
//使用饿汉式创建一个购物车类
class Cart{
private final List<Spu> spuList;
//私有化构造器
private Cart(){
spuList = new ArrayList<>();
}
//本类内部创建实例对象
private final static Cart instance;
//使用静态代码块创建实例对象
static {
instance = new Cart();
}
//提供一个静态方法,返回实例对象
public static Cart getInstance(){
return instance;
}
public void addSpu(String spuName, int spuNum){
Spu spu = new Spu(spuName,spuNum);
this.spuList.add(spu);
}
public void printSpuList(){
for (Spu spu :
spuList) {
System.out.println(spu.getSpuName()+" "+spu.getSpuNum());
}
}
}
3、懒汉式(线程不安全)
java
class Cart{
private final List<Spu> spuList;
//私有化构造器
private Cart(){
spuList = new ArrayList<>();
}
//本类内部创建实例对象
private static Cart instance;
//提供一个静态方法,返回实例对象
//在调用getinstance的时候 才会去创建一个对象
public static Cart getInstance(){
if (instance == null){
instance = new Cart();
}
return instance;
}
public void addSpu(String spuName, int spuNum){
Spu spu = new Spu(spuName,spuNum);
this.spuList.add(spu);
}
public void printSpuList(){
for (Spu spu :
spuList) {
System.out.println(spu.getSpuName()+" "+spu.getSpuNum());
}
}
}
4、懒汉式(同步方法)
java
class Cart{
private final List<Spu> spuList;
//私有化构造器
private Cart(){
spuList = new ArrayList<>();
}
//本类内部创建实例对象
private static Cart instance;
//提供一个静态方法,返回实例对象
//在调用getinstance的时候 才会去创建一个对象
//使用同步方法
public static synchronized Cart getInstance(){
if (instance == null){
instance = new Cart();
}
return instance;
}
public void addSpu(String spuName, int spuNum){
Spu spu = new Spu(spuName,spuNum);
this.spuList.add(spu);
}
public void printSpuList(){
for (Spu spu :
spuList) {
System.out.println(spu.getSpuName()+" "+spu.getSpuNum());
}
}
}
5、懒汉式(同步代码块)
java
class Cart{
private final List<Spu> spuList;
//私有化构造器
private Cart(){
spuList = new ArrayList<>();
}
//本类内部创建实例对象
private static Cart instance;
//提供一个静态方法,返回实例对象
//在调用getinstance的时候 才会去创建一个对象
//使用同步代码块
public static Cart getInstance(){
if (instance == null){
synchronized (Cart.class){
instance = new Cart();
}
}
return instance;
}
public void addSpu(String spuName, int spuNum){
Spu spu = new Spu(spuName,spuNum);
this.spuList.add(spu);
}
public void printSpuList(){
for (Spu spu :
spuList) {
System.out.println(spu.getSpuName()+" "+spu.getSpuNum());
}
}
}
6、双重检查
java
class Cart{
private final List<Spu> spuList;
//私有化构造器
private Cart(){
spuList = new ArrayList<>();
}
private volatile static Cart instance;
public static Cart getInstance(){
if (instance == null){
synchronized (Cart.class){
if (instance == null){
instance = new Cart();
}
}
}
return instance;
}
public void addSpu(String spuName, int spuNum){
Spu spu = new Spu(spuName,spuNum);
this.spuList.add(spu);
}
public void printSpuList(){
for (Spu spu :
spuList) {
System.out.println(spu.getSpuName()+" "+spu.getSpuNum());
}
}
}
7、静态内部类
java
class Cart{
private final List<Spu> spuList;
//私有化构造器
private Cart(){
spuList = new ArrayList<>();
}
//创建一个静态内部类
private static class Instance{
private final static Cart INSTANCE = new Cart();
}
//提供一个静态方法,返回实例对象
public static Cart getInstance(){
return Instance.INSTANCE;
}
public void addSpu(String spuName, int spuNum){
Spu spu = new Spu(spuName,spuNum);
this.spuList.add(spu);
}
public void printSpuList(){
for (Spu spu :
spuList) {
System.out.println(spu.getSpuName()+" "+spu.getSpuNum());
}
}
}