精华内容
下载资源
问答
  • 单例模式懒汉和饿汉

    2020-12-01 11:03:32
    这是饿汉式,不管用不用,先创建一个对象,线程安全 public class SingletonTest01 { public static void main(String[] args) { Bank bank1=Bank.getInstance(); Bank bank2=Bank.getInstance(); System.out....

    这是饿汉式,不管用不用,先创建一个对象,线程安全

    public class SingletonTest01 {
        public static void main(String[] args) {
            Bank bank1=Bank.getInstance();
            Bank bank2=Bank.getInstance();
            System.out.println(bank1==bank2);
        }
    }
    class Bank {
    
        private Bank(){
    
        }
        private static Bank Instance=new Bank();
        public  static Bank getInstance(){//这里要用public因为外部要调用,
            return Instance;
        }
    }
    

    这是懒汉式,直到用的时候我们才创建对象,线程不安全
    下面的举例都不进行测试了。

    public class SingletonTest02 {
        public static void main(String[] args) {
    
        }
    }
    class Order{
        private Order(){
    
        }
        private static Order instance=null;//这里要赋值为空,这样才能实现用的时候才创建,不用的话就不用创建
        public static Order getInstance(){
            if(instance==null){//因为这里有个判断,两个线程可能同时进入if语句,所以可能会创建两个对象,此时就不符合单例模式了,线程不安全
                instance=new Order();
            }
                return instance;
        }
    }
    

    这里线程不安全,需要加上synchronized关键字

    public class SingletonTest03 {
    }
    
    class Book{
        private Book(){
    
        }
        private static Book instance =null;
      
           public static synchronized Book getInstance(){
          if (instance ==null){
             instance =new Book();
          }
         return instance;
      }
    }
    

    这是Singleton的升级版,这是线程安全的,同步方法的锁是Book.class,
    但是此种方法不高效,就第一个线程拿到了需要创建之外,其他的都得等,而且也都是直接返回instance,效率很低。
    就相当于买书,书只有一本,第一个人买走后,后面来的人都需要进来店确定一下,不如直接在门口挂账牌子,书已经售空

    改进方案

    public class SingletonTest03 {
    }
    
    class Book{
        private Book(){
    
        }
    	private static Book instance =null;
    	public static Book getInstance(){
            if(instance==null){
                synchronized (Book.class){
                    if (instance==null){//这里在进行判断一下的原因是,刚开始可能有好几个线程都在锁的前面等,当第一个创建完成之后,后面等的几个就不需要创建了
                        instance=new Book();
                    }
                }
            }
            return instance;
        }
        }
    

    因为在多线程情况下可能存在指令重排,所以最终应该是

    public class SingletonTest03 {
    }
    
    class Book{
        private Book(){
    
        }
    	private static volatile Book instance =null;
    	public static Book getInstance(){
            if(instance==null){
                synchronized (Book.class){
                    if (instance==null){
                        instance=new Book();
                    }
                }
            }
            return instance;
        }
        }
    

    在instance=new Book();这一步,底层需要执行三步
    1.分配对象内存空间
    2.初始化对象
    3.设置instance指向刚分配的内存地址,此时instance!=null。
    当时因为指令重排,2,3之间不存在数据依赖关系,这三步的执行顺序可能会变为1,3,2。此时可能就在黑没有初始化对象好,另一个线程在上面的if上判断instance==null已经失败了,因为instance已经指向了内存空间,只不过对象没有初始化而已,所以直接就返回了一个没有初始化的instance,此时就会出错。所以还是需要volatile关键字。

    展开全文
  • 单例懒汉模式和饿汉模式,以及线程安全版懒汉模式 单例模式:是一种常见的设计模式,一个类只能创建出一个实例对象,这就是单例模式写法(封装)。 封装:就是对复杂事物的一种简化。可以说是对具有相同特征的一类...

    单例懒汉模式和饿汉模式,以及线程安全版懒汉模式

    单例模式:是一种常见的设计模式,一个类只能创建出一个实例对象,这就是单例模式写法(封装)。

    封装:就是对复杂事物的一种简化。可以说是对具有相同特征的一类事物进行抽象封装,抽象程度越高,封装就越彻底。这样有助于建立各个系统之间的低耦合关系,提高系统的独立性。其实封装并不是一种技术,而是一种思想。当一件事变得复杂,就需要从一个更高的层次来进行管理。
    懒汉模式:在调用静态方法时才能创建对象
    1. 将构造器私有化。
    2. 一个静态私有属性存放当前类常量的对象变量。
    3. 提供一个公有的静态方法,获取到之前对象变量。
      懒汉式单例的实现没有考虑线程安全问题,它是线程不安全的
    package im;
    
    /**
    
    - 懒汉模式
    - @author MF
    *
     */
    public class Person {
      private static Person person; 
      private Person() {	
    }
      public static Person getPerson() {
    	if(person == null) {
    		person=new Person();
    		
          }
          return person;
      }
    
    }
    
    
    饿汉模式:类加载完成就创建对象
    1. 将构造器私有化。
    2. 私有静态属性中存放创建的对象,并且在类加载完成就创建好了。
    3. 提供一个公有的静态方法,获取之前对象变量。
      饿汉式在类创建的同时就已经创建好一个静态的对象供系统使用,以后不再改变,所以是线程安全的。
    package im;
    
    /**
      *  饿汉模式
     * @author MF
     *
     */
    public class Person2 {
    	
    	private static Person2 person =new Person2();
    	
    	private Person2() {
    	}
    	public static Person2 getPerson() {
    		return person;
    	}
    
    }
    
    
    线程安全版懒汉模式 利用synchronized作用于当前类对象加锁,进入同步代码前要获得当前类对象的锁
    package im;
    
    import java.util.concurrent.locks.ReentrantLock;
    
    public class Person3 {
    	
    	private static volatile Person3 p;//保证了原子性,一致性
    	//private static ReentrantLock lock =new ReentrantLock();
    	
    	private Person3() { System.out.println(5);
    	}
    	
    	public static Person3 getPerson() {
    		if(p==null) {//如果对象存在,直接返回,不需要进行等待了,直接返回,效率高
    			synchronized (Person.class) {
    				if(p==null) {
    					p=new Person3();
    				}
                   /**
    				 *  开辟空间                    1
    				 *  赋初始值                    2 
    				 *  返回地址给变量p              3
    				 */
    				
    			}
    		}
    		return p;
    		
    	}
    
    }
    

    前几天被朋友说到,我的CSDN是在一直摸鱼,一周就更新一篇,内容还少。emmmmm,我不是咸鱼,好吧。接下来我会提高自己的更新量和文章水平的。
    在这里插入图片描述

    展开全文
  • 针对于其对象的创建时间,分为懒汉模式和饿汉模式 懒汉模式下:使用该类的情况下在进行对象的创建,而饿汉模式下,则是直接将该类及其对象直接加载进内存 两种模式的测试,因为直接私有了构造方法,因此该对象在该...

    对于单例模式就是保证内存中仅仅创建一个该类的实例对象

    针对于其对象的创建时间,分为懒汉模式和饿汉模式

    懒汉模式下:使用该类的情况下在进行对象的创建,而饿汉模式下,则是直接将该类及其对象直接加载进内存

    两种模式的测试,因为直接私有了构造方法,因此该对象在该类的内部直接创建,因此返回该类的对象的方法需以static修饰符进行修饰。然后便可以调用该类的其他公共方法,且保证该类的对象仅在内存中加载过一次。

    代码如下:

    懒汉模式:

    public class LazyPattern {
        private static LazyPattern pattern;
        private LazyPattern(){
            
        }
        public static LazyPattern getLazyPattern() {
            if (pattern==null) {
                pattern = new LazyPattern();
            }
            return pattern;
        }
        public void function() {
            System.out.println("懒汉的方法");
        }

    }
    饿汉模式:

    public class HPattern {
        private static HPattern pattern = new HPattern();
        private HPattern() {
            
        }
        public static HPattern getHPattern() {
            return pattern;
        }
        public void function() {
            System.out.println("饿汉的方法");
        }

    }

    测试类的代码:

    public class Test {
    public static void main(String[] args) {
        HPattern pattern = HPattern.getHPattern();
        pattern.function();
        LazyPattern pattern2 = LazyPattern.getLazyPattern();
        pattern2.function();
    }
    }
     

    展开全文
  • java 单例模式 懒汉和饿汉

    千次阅读 2018-09-30 15:39:37
    单线程下的单例模式 定义: 确保一个类只有一个实例,并提供一个全局访问点。 单例代码: package wfb.pattern; public class Singleton { private static Singleton instance; private Singleton() { System....

    单线程下的单例模式

    定义:

    确保一个类只有一个实例,并提供一个全局访问点。

    单例代码:

    package wfb.pattern;
    
    
    public class Singleton {
    	private static Singleton instance;
    	private Singleton() {
    		System.out.println("实例化了一个新的单例");
    	}
    	public static Singleton getInstance() {
    		if(instance == null) {
    			instance = new Singleton();
    		}
    		return instance;
    	}
    }
    
    

    测试代码:

    package wfb.patthernTest;
    
    import org.junit.Test;
    
    import wfb.pattern.Singleton;
    
    public class SingletonTest {
    	@Test
    	public void testSinglon1() {
    		Singleton singlon1 = Singleton.getInstance();
    		Singleton singlon2 = Singleton.getInstance();
    	}
    	@Test
    	public void testSingleton2() throws Exception {
    		while(true) {
    			new Thread(new Runnable() {
    				public void run() {
    					try {
    						Thread.sleep(10);
    					} catch (InterruptedException e) {
    						e.printStackTrace();
    					}
    					Singleton singlon = Singleton.getInstance();
    				}
    			}).start();
    		}
    	}
    }
    
    

    测试结果:

    单线程 :
    单线程下,只会有一个实例
    多线程 :
    在多线程的环境下,简单的单例模式生成了多个实例

    原因分析:

        如果多个线程同时走到if(instance == null)的判断语句,会因为还未创建实例而进入到实例化代码,从而导致了单件被实例化多次。换句话说,根本原因是if(instance == null) instance = new Singleton()这两步操作不是原子性的。
    为此,我们有两种解决方法:
    1.在类加载后就初始化instance,之后就不在需要创建实例了。
    2.用同步包起这两步操作,从而使得它具有原子性。
    懒汉和饿汉模式就这两种方法分别给出了多线程下单例模式的解决方案。

    多线程下的单例模式

    饿汉代码:

    package wfb.pattern;
    //饿汉模式通过提前初始化一个实例来解决多线程问题
    public class SingletonHungry {
    	private static SingletonHungry instance = new SingletonHungry();
    	private SingletonHungry() {
    		System.out.println("实例化了一个新的单例");
    	}
    	public static SingletonHungry getInstance() {
    		return instance;
    	}
    }
    

    饿汉测试:

    @Test
    	public void testSingletonHungry() throws Exception{
    		while(true) {
    			new Thread(new Runnable() {
    				public void run() {
    					try {
    						Thread.sleep(10);
    					} catch (InterruptedException e) {
    						e.printStackTrace();
    					}
    					SingletonHungry singletonHungry = SingletonHungry.getInstance();
    				}
    			}).start();
    		}
    	}
    

    饿汉结果:

    只执行了一次实例化

    懒汉代码:

    package wfb.pattern;
    //懒汉模式通过同步解决多线程问题。
    public class SingletonLazy {
    	private static SingletonLazy instance;
    	private SingletonLazy() {
    		System.out.println("实例化了一个新的单例");
    	}
    	public static SingletonLazy getInstance() {
    		if(instance != null) return instance;//为了增加效率,当拥有了实例后,我们直接返回实例。因为拥有了实例后,状态就跟饿汉一致了,显然不会发生线程问题。
    		synchronized (SingletonLazy.class) {//因为是静态方法,所以用类做同步锁
    			if(instance == null) instance = new SingletonLazy();
    			return instance;
    		}
    	}
    }
    

    懒汉测试:

    @Test
    	public void testSingletonLazy() throws Exception{
    		while(true) {
    			new Thread(new Runnable() {
    				public void run() {
    					try {
    						Thread.sleep(10);
    					} catch (InterruptedException e) {
    						e.printStackTrace();
    					}
    					SingletonLazy singletonLazy = SingletonLazy.getInstance();
    				}
    			}).start();
    		}
    	}
    

    懒汉结果:

    只执行了一次实例化

    展开全文
  • 实现: 1 公开静态的对外访问方法 2 私有的构造方法(保证不被外部调用) ... // 饿汉单例 public static void main(String[] args) { Instance1 d1 = Instance1.getInstance1(); Instance1 d2 = ...
  • 单例模式: 关键点: 1、一个类只有一个实例; 2、类自行创建该实例; 3、类自行向整个系统提供该实例。 代码展示: namespace SingleTon { /// <summary> /// 懒汉单例、多线程安全 /// 比较懒...
  • 设计模式指的是一套被反复使用,多数人知晓的,经过分类编目的...对于配置文件,工具类,线程池,缓存,日志对象等,如果创造出多个实例,就会导致许多问题,如占用过多的资源,不一致的结果等,采用单例模式解决。 常
  • 懒汉模式 懒汉模式没啥好讲,直接代码 public class test{ public static void main(String args[]){ Student student1 = Student.getInstance(); Student student2 = Student.getInstance(); ...
  • 概念: java中单例模式是一种常见的设计模式,单例模式的写法有好几种,这里主要介绍三种:懒汉式单例、饿汉式单例、登记式单例。 单例模式有以下特点: 1、单例类只能有一个实例。 2、单例类必须自己创建自己的...
  • 单例模式懒汉饿汉区别就是是否在程序一开始就创建单例 懒汉:很懒,所以一开始不创建单例,等到需要用到的时候才创建单例,用时间换空间。 注意:懒汉单例是线程不安全的,如果有两个线程,我们称它们为线程1...
  • 单例模式懒汉和饿汉式区别

    万次阅读 多人点赞 2018-04-11 11:19:45
    单例模式懒汉和饿汉式区别 单例模式(Singleton Pattern)是 Java 中最简单的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。 这种模式涉及到一个单一的类,该类负责创建...
  • import java.awt.image.SampleModel;...* 单例模式 * */ public class Single { //私有的构造函数 private Single(){ } //静态的成员变量 private static Single single; public void say(){.
  • 单例模式主要解决一个全局使用的类频繁的创建销毁的问题。 单例模式是一种常用的软件设计模式,其定义是单例对象的类只能允许一个实例存在。这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有...
  • 单例模式:(1)一个类只有一个实例;  (2)它必须自行创造这个实例;  (3)它必须自行向整个系统提供这个实例。 《单例》 package util; /**  *   * 单例模式  * 懒汉模式读取配置文件  * 线程不安全 ...
  • 饿汉单例懒汉单例 转载于:https://www.cnblogs.com/jyfby/p/8961600.html
  • 一、单例模式懒汉和饿汉式区别 ​ 单例模式(Singleton Pattern)是 Java 中最简单的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。 这种模式涉及到一个单一的类,该类负责...
  • 单例模式三要素: a)私有构造方法(这样外界就没办法创建对象) b)私有静态引用指向自己实例 c)以自己实例为返回值的公有静态方法 (对外暴露接口获取实例) 在Spring中创建的Bean实例默认都是单例模式存在的。...
  • 单例模式(Singleton Pattern)是 Java 中最简单的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。 这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象...
  • 单例模式懒汉饿汉

    2019-12-02 12:14:34
    曾丹模拟的时候,讲到单例模式,她问我为什么叫懒汉?为什么叫饿汉懒汉式:就是非常懒,只有当你要用他的时候,他才会去行动,去产生实例类加载时不初始化 在类加载时,不创建实例,因此类加载速度快,但运行...
  • 饿汉单例 package com.jialidun.gof.single; //饿汉单例 public class Hungry { //1.构造器私有 private Hungry(){ ... private final static Hungry HUNGRY = new Hungry();...懒汉单例 .

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 3,747
精华内容 1,498
关键字:

单例模式懒汉和饿汉