zoukankan      html  css  js  c++  java
  • java 单例

    一.饿汉模式(类加载的时候就会实例化,线程安全)

    复制代码
     1 package com.sun.singleton;
     2 
     3 //饿汉模式
     4 public class Singleton {
     5 
     6     //将构造函数私有化,不允许外部直接调用创建对象
     7     private Singleton(){
     8         
     9     }
    10     //内部创建类的唯一实例,用private static 修饰(加载类时实例化一次,之后无论调用几次用的都是这一个实例)
    11     private static Singleton instance = new Singleton();
    12     
    13     //提供一个外部用于获取实例的方法,用 public static 修饰
    14     public static Singleton getInstance(){
    15         return instance;
    16     }
    17 
    18 }
    复制代码

    二. 懒汉模式(比较懒,所以只有调用方法getInstance时候根据判断结果才会实例化,而且线程不安全)

            线程不安全原因:如果是单线程那懒汉模式也没有问题,但如果是多线程且没有加锁处理就不行了。不如A,B两个线程,A线程首先调用getInstance方法,判断instance 为空,即将创建实例,就在这时cpu切换到B线程,A暂停。B线程调用getInstance方法判断instance为空,然后创建实例,创建结束后B线程结束,A线程开始继续执行,注意:此时A线程已经判断过instance为空,那么会继续创建实例,这样线程AB都各自创建了实例,就不再是单例模式。------所以懒汉模式要加锁同步。

    复制代码
    package com.sun.singleton;
    //懒汉模式(线程不安全)
    public class Singleton2 {
        
        //1.构造函数私有化,不允许外部直接调用
        private Singleton2(){
            
        }
        
        //2.只是声明类的唯一实例,这时没有真正实例化,使用private static 修饰
        private static Singleton2 instance;
        
        //3.提供获取实例的方法,用public static修饰
    // (1).解决线程不安全-------加同步(每个线程每次获取实例都要判断下锁,效率比较低) public static synchronized Singleton2 getInstance(){ if(instance == null){ return instance = new Singleton2(); } return instance; } //(2).解决线程不安全-----双重检查锁定(提高效率) public static Singleton2 getInstance2(){ /*如果第一个线程获取到了单例的实例对象,后面的线程再获取实例的时候不需要进入同步代码块中了*/ if(instance == null){ synchronized (Singleton2.class) { if(instance == null){ instance = new Singleton2(); } } } return instance; } }
    复制代码

     输出:

    复制代码
    package com.sun.singleton;
    
    public class Main {
    
        public static void main(String[] args) {
            
            //实例化两次作比较测试
            //饿汉式
            Singleton s1= Singleton.getInstance();
            Singleton s2= Singleton.getInstance();
            if(s1==s2){
                System.out.println("饿汉式是同一个实例");
            }else{
                System.out.println("饿汉式不是同一个实例");
            }
            //懒汉式
            Singleton2 s3 = Singleton2.getInstance();
            Singleton2 s4 = Singleton2.getInstance();
            if(s3==s4){
                System.out.println("懒汉式是同一个实例");
            }else{
                System.out.println("懒汉式不是同一个实例");
            }
    
        }
    
    }
    复制代码

     结果截图:

    说明单例模式是同一个对象实例化是共享一个内存空间。

    两者区别:

               饿汉模式:类加载的时候比较慢(加载时候实例化),但是运行时候比较快,线程安全。

               懒汉模式:类加载的时候比较快,但是运行时候比较慢(调用方法的时候实例化),线程不安全。

  • 相关阅读:
    asp.net禁用頁面緩存
    SQL排序方法,EXEC法和CASE WHEN法
    Web Service 基础连接已经关闭的解决方案
    用CSS写TABLE边框
    SQL2000分页存储过程,针对表,2005有自带的row_number
    GridView RowCommand事件中取得當前行
    取得Repeter中數據項,如TR
    FireFox自动撑高层解决方案
    PostgreSql 添加语言语法
    CSS设置图片居中
  • 原文地址:https://www.cnblogs.com/llq5/p/5092280.html
Copyright © 2011-2022 走看看