《设计模式之单例模式》

本文详细介绍了单例模式的概念及其在Java中的实现方式,包括饿汉式和懒汉式的区别,并通过一个具体的售票系统案例展示了饿汉式单例模式的应用。

1. 单例模式的定义

单例模式的英文定义:
Ensure a class has only one instance, and provide a global point of access to it.
大体的意思就是确保一个类有且只有一个实例,并且提供一个全局的指针来操作该类。单例模式的主要意思就是确保一个类只有一个实例。单例模式可以用来建立目录、数据库连接等需要单线程操作的场合,用于对系统资源的控制。
由于Java语言的特点,存在两种单例形式:
(1)饿汉式单例类:当Java虚拟机加载该类的时候,就对该类进行实例化;
(2)懒汉式单例类:第一次创建该类的引用的时候,才对该类进行实例化。
饿汉单例类的StarUML类图:
这里写图片描述
对于此类图而言,首先构造函数私有,外部无法对该类进行实例化,其次包含一个静态的该类的私有的引用和一个返回该引用的公共的静态方法。如此一来饿汉式单例类就创建完成。如下代码为StarUML所生成的代码:

    import java.util.*;

    /**
     * 
     */
    public class Singleton {

        /**
         * Default constructor
         */
        private Singleton() {//public修改成为private
        }

        /**
         * 
         */
        private static Singleton instance = new Singleton();

        /**
         * @return
         */
        public static Singleton getInstance() {
            // TODO implement here
            return instance;//返回instance
        }

    }

懒汉单例类的StarUML类图:
这里写图片描述
如下代码为StarUML所生成的代码:


    import java.util.*;

    /**
     * 
     */
    public class Singleton {

        /**
         * Default constructor
         */
        **private** Singleton() {//public修改成为private
        }

        /**
         * 
         */
        private static Singleton instance = null;

        /**
         * @return
         */
        public static Singleton getInstance() {
            // TODO implement here
            if(instance==null){//为保证线程安全采取double check并且加入synchronized保证线程同步
                synchronized(Singleton.class){
                    if(instance==null){
                        instance = new SIngleton();
                    }
            }
            return instance;
        }

    }

懒汉式单例模式和饿汉式单例模式的区别,饿汉式单例模式在同一个jvm下能保证在创建线程时只创建一个对象,这与jvm模式有关,对于懒汉式单例模式需要使用synchronized关键字保证线程同步。

2.测试单例模式(饿汉式单例模式)

这个例子用来大致模拟大家买票的行为:
Ticket.java

    package fengqi.wang;

    public class Ticket {

        private static Ticket instance = new Ticket();
        private int totalTickets = 20;

        private Ticket() {

        }

        public static Ticket getInstance() {
            return instance;
        }

        synchronized public int sell() {// 保证线程同步
            if (totalTickets > 0) {
                return --totalTickets;
            }
            return -1;
        }
    }

TicketCounter.java

    package fengqi.wang;

    public class TicketCounter implements Runnable {

        private String name = "";

        public TicketCounter(String name) {
            // TODO Auto-generated constructor stub
            this.name = name;
        }

        @Override
        public void run() {
            // TODO Auto-generated method stub
            Ticket t = Ticket.getInstance();
            while (true) {
                int count = t.sell();
                if (count > -1) {
                    System.out.println(this.name + "卖出了第" + (20 - count) + "票。");
                } else {
                    System.out.println("票已售罄!!!");
                    break;
                }
                try {
                    Thread.sleep(10);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }

    }

TestTicketCounter.java

    package fengqi.wang;

    public class TestTicketCounter {
    public static void main(String[] args) {

            Thread t1 = new Thread(new TicketCounter("窗口1"));
            Thread t2 = new Thread(new TicketCounter("窗口2"));
            Thread t3 = new Thread(new TicketCounter("窗口3"));
            Thread t4 = new Thread(new TicketCounter("窗口4"));

            t1.start();
            t2.start();
            t3.start();
            t4.start();

        }
    }

3.测试结果

窗口2卖出了第2票。
窗口1卖出了第1票。
窗口3卖出了第3票。
窗口4卖出了第4票。
窗口1卖出了第6票。
窗口3卖出了第7票。
窗口2卖出了第5票。
窗口4卖出了第8票。
窗口3卖出了第11票。
窗口4卖出了第12票。
窗口1卖出了第9票。
窗口2卖出了第10票。
窗口1卖出了第13票。
窗口3卖出了第16票。
窗口4卖出了第15票。
窗口2卖出了第14票。
窗口1卖出了第17票。
窗口4卖出了第19票。
窗口3卖出了第18票。
窗口2卖出了第20票。
票已售罄!!!
票已售罄!!!
票已售罄!!!
票已售罄!!!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值