小白学java日记day22--单例实例

定义
一个类只允许有一个对象 , 建立一个全局的访问点 , 提供出去供大家使用 .
分析 :
1. 我们肯定要建立一个单例类来描述
2. 只允许有一个对象
3. 全局的访问点 : 说的就是当前的 s ---- 通过 static 实现的
4. 提供出去
5. 给大家使用
总括 :1. 传值 . 作为全局的访问点 .
解决一个全局使用的类,频繁创建和销毁。拥有对象的唯一性,并保证内存中对象的唯一。
可以节省内存,因为单例共用一个实例,有利于 Java 的垃圾回收机制。也就是控制资源使
用,通过线程同步来控制资源的并发访问;
控制实例产生的数量,达到节约资源的目的;
使用场景
1. 统计当前在线人数(网站计数器):用一个全局对象来记录。
2. 打印机(设备管理器):当有两台打印机,在输出同一个文件的时候只一台打印机进行输
出。
3. 数据库连接池(控制资源):一般是采用单例模式,因为数据库连接是一种连接数据库资
源,不易频繁创建和销毁。
数据库软件系统中使用数据库连接池,主要是节省打开或者关闭数据库连接所引起的效率损
耗,这种效率的损耗还是非常昂贵的,因此用单例模式来维护,就可以大大降低这种损耗。
4. 应用程序的日志(资源共享):一般日志内容是共享操作,需要在后面不断写入内容所以通
常单例设计。
示例代码:
/*
1.我们肯定要建立一个单例类来描述
2.只允许有一个对象
3.全局的访问点:说的就是当前的s----通过static实现的
4.提供出去
5.给大家使用
 */
public class Demo {
    public static void main(String[] args) {
//        SingleInstance singleInstance1=new SingleInstance();
//        SingleInstance singleInstance2=new SingleInstance();
//        System.out.println(singleInstance1==singleInstance2);//false
        //通过公共方法找单例对象
        SingleInstance singleInstance1 = SingleInstance.getSingleInstance();
        SingleInstance singleInstance2 = SingleInstance.getSingleInstance();
        System.out.println(singleInstance1 == singleInstance2);//true

        //实现功能:有A,B类
        //在A类中有属性num1 B类中有属性num2
        //num1的值是4,
        //
        A a=new A();
        a.num1=4;

    }
    static class A{
        int num1;
    }
    static class B{
        int num2;
    }
}


//饿汉式:在声明SingleInstance变量时直接赋值
class SingleInstance {
    //2.生成一个静态的私有的SingleInstance(私有保证有唯一的对象)
    //不加final,引用后面的地址可以改变,加final后singleInstance的引用变成了常量,地址不能改变了
    //private 目的是为了外界不能访问,改变singleInstance地址(加上final后可以去掉一般习惯性写上)
    private final static SingleInstance singleInstance = new SingleInstance();

    //1.将构造方法私有化
    private SingleInstance() {

    }

    //3.静态的公共的方法
    public static SingleInstance getSingleInstance() {
        return singleInstance;
    }

    //4.重写clone方法,让这个方法也返回当前的单例类的唯一对象
    //注意:这个方法一般可以不写
    @Override
    protected Object clone() throws CloneNotSupportedException {
        return singleInstance;
    }
}

//懒汉式:在声明SingleInstance1变量时先不进行赋值,等到实际使用的时候在完成赋值
class SingleInstance1 {
    //2.生成一个静态的私有的SingleInstance(私有保证有唯一的对象)
    private static SingleInstance1 singleInstance1 = null;

    //1.将构造方法私有化
    private SingleInstance1() {
    }
    //3.静态的公共的方法
    public static SingleInstance1 getSingleInstance1() {
        //外层if 减少了synchronized判断的次数,在保证同步的前提下,提高了到哪里使用的效率
        if (singleInstance1 == null){//控制不了同步,减少同步判断的次数
            synchronized (SingleInstance.class) {//用当前类的字节码文件对象作为锁
                if (singleInstance1 == null) {
                    singleInstance1 = new SingleInstance1();
                }
            }
        }
        return singleInstance1;
    }

    //4.重写clone方法,让这个方法也返回当前的单例类的唯一对象
    //注意:这个方法一般可以不写
    @Override
    protected Object clone() throws CloneNotSupportedException {
        return singleInstance1;
    }
}

 

案例:

有一个订单文件order.txt

orderid:20 ordername:shoes orderprice:1000 orderday:1990-10-10
orderid:21 ordername:phones orderprice:1100 orderday:1990-11-10
orderid:17 ordername:computers orderprice:1300 orderday:1990-12-11

1.需要将数据存入List<Order>
2.将list存入单例对象,使其在全局可见
3.对list所在的单例进行序列化操作,并反序列化测试

/*
有一个订单文件order.txt

    orderid:20	ordername:shoes	orderprice:1000	orderday:1990-10-10
    orderid:21	ordername:phones	orderprice:1100	orderday:1990-11-10
    orderid:17	ordername:computers	orderprice:1300	orderday:1990-12-11

1.需要将数据存入List<Order>
2.将list存入单例对象,使其在全局可见
3.对list所在的单例进行序列化操作,并反序列化测试

分析:
IO流
NIO流
集合
面向对象
单例设计模式
序列化/反序列化
 */
public class test {
    public static void main(String[] args) {
        //1.需要将数据存入List<Order>
        List<Order> list=getDate();
        System.out.println(list);
        //2.将list存入单例对象,使其在全局可见
        SinleInstance s=SinleInstance.getInstance();
        s.list=list;
        test();
        //3.对list所在的单例进行序列化操作,并反序列化测试
        //writeToFile();
        readFromFile();
    }
    //1.需要将数据存入List<Order>
    public static List<Order> getDate(){
        List<Order> list1=new ArrayList<>();
        try {
            List<String>   list = Files.readAllLines(Paths.get("C:\\Desktop\\order.txt"));
            //将数据转存到Order
            for (String s: list) {
                list1.add(new Order(s));
            }

        } catch (IOException e) {
            e.printStackTrace();
        }

        return list1;
    }
    static public class Order implements Serializable{
      private String orderid;
      private String ordername;
      private double orderprice;
      private Date orderday;


        public String getOrderid() {
            return orderid;
        }

        public void setOrderid(String orderid) {
            this.orderid = orderid;
        }

        public String getOrdername() {
            return ordername;
        }

        public void setOrdername(String ordername) {
            this.ordername = ordername;
        }

        public double getOrderprice() {
            return orderprice;
        }

        public void setOrderprice(double orderprice) {
            this.orderprice = orderprice;
        }

        public Date getOrderday() {
            return orderday;
        }

        public void setOrderday(Date orderday) {
            this.orderday = orderday;
        }
        public Order(){}
        public Order(String orderid, String ordername, double orderprice, Date orderday) {
            this.orderid = orderid;
            this.ordername = ordername;
            this.orderprice = orderprice;
            this.orderday = orderday;
        }

        @Override
        public String toString() {
            return "Order{" +
                    "orderid=" + orderid +
                    ", ordername='" + ordername + '\'' +
                    ", orderprice=" + orderprice +
                    ", orderday='" + orderday + '\'' +
                    '}';
        }

        //完成数据切割
        public Order(String src){
            String[] srcs=src.split("\t");
            for (String s : srcs) {
                String[] pair=s.split(":");
                //去空格
                String key=pair[0].trim();
                String value=pair[1].trim();
                //正则表达式
                if (key.equals("orderid")){
                    this.orderid=value;
                }else if (key.equals("ordername")){
                    this.ordername=value;
                }else if (key.equals("orderprice")){
                    this.orderprice= Double.parseDouble(value);
                }else if (key.equals("orderday")){
                    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
                    try {
                        this.orderday = simpleDateFormat.parse(value);
                    } catch (ParseException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }
    //2.将list存入单例对象,使其在全局可见
    public static void test(){
        SinleInstance s=SinleInstance.getInstance();
        System.out.println("单例对象中的list"+s.list);
    }
    //3.对list所在的单例进行序列化操作,并反序列化测试
    public static void writeToFile(){
        try(ObjectOutputStream objectOutputStream=new ObjectOutputStream(new FileOutputStream("0609--单例\\danli.txt"))){
            objectOutputStream.writeObject(SinleInstance.getInstance());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    public static void readFromFile(){
        try(ObjectInputStream objectInputStream=new ObjectInputStream(new FileInputStream("0609--单例\\danli.txt"))) {
            try {
                SinleInstance s=(SinleInstance)objectInputStream.readObject();
                System.out.println("逆序列化后的list:"+s.list);
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
//单例类
class SinleInstance implements Serializable {
    private static final long serialVersionUID=-2848937489372589732L;
    private static SinleInstance s=null;
    private SinleInstance(){}
    public static SinleInstance getInstance(){
        if (s==null){
            synchronized (SinleInstance.class){
                if (s==null){
                    s=new SinleInstance();
                }
            }
        }
        return s;
    }
    //功能区
    List<test.Order> list=new ArrayList<>();
}

 注意:要把单例单独一写一个类出来,不要写在类里。

例如:

/阿里总裁到广州,北京,上海访问
//总裁属性:姓名,年龄,性别
//要求:使用单例实现
//阿里总裁到广州,北京,上海访问
//总裁属性:姓名,年龄,性别
//要求:使用单例实现
public class homework {
    public static void main(String[] args) {
        visitBeijing();
        visitGuangzhou();
        visitShanghai();
    }
    public static void visitGuangzhou(){
        SingleInstance singleInstance = SingleInstance.getS();
        System.out.println("总裁"+singleInstance.president.getName()+"到广州开会");
    }
    public static void visitBeijing(){
        SingleInstance singleInstance = SingleInstance.getS();
        System.out.println("总裁"+singleInstance.president.getName()+"到北京开会");
    }
    public static void visitShanghai(){
        SingleInstance singleInstance = SingleInstance.getS();
        System.out.println("总裁"+singleInstance.president.getName()+"到上海开会");
    }
}
enum Gender{
    Male,FeMale
}
class President{
    private String name;
    private int age;
    private Gender gender;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public Gender getGender() {
        return gender;
    }

    public void setGender(Gender gender) {
        this.gender = gender;
    }

    public President(String name, int age, Gender gender) {
        this.name = name;
        this.age = age;
        this.gender = gender;
    }
}
class SingleInstance{
    private static SingleInstance s = null; private SingleInstance(){}
    public static SingleInstance getS() {
        if (s == null){
            synchronized (SingleInstance.class){
                if (s == null){ s = new SingleInstance();
                }
            }
        }
        return s;
    }
    President president = new President("云云",40,Gender.Male);
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值