Java单例模式 您所在的位置:网站首页 java锁方法是怎么样的 Java单例模式

Java单例模式

2023-03-24 11:35| 来源: 网络整理| 查看: 265

目录 Java单例模式1.什么是单例模式?2.怎么样实现单例模式?3.单例模式中的饿汉模式4.单例模式中的懒汉模式4.1 懒汉模式线程安全问题4.1.1 多线程懒汉模式 synchronized加锁4.1.2多线程懒汉模式修改

Java单例模式 1.什么是单例模式?

单例模式保证某个类在程序中有且只有一个对象。

2.怎么样实现单例模式?

  1.创建对象要调用构造方法

  2.让构造器私有化,不能在其他类中创建对象

  3.构造器私有化后,要提供一个方法获取唯一可用的对象

3.单例模式中的饿汉模式 class Singleton{ private static Singleton singleton=new Singleton(); private Singleton(){}; // 调用此方法时,singleTon对象已经创建了,再次创建对象是同一个对象 public static Singleton getInstance(){ return singleton; } } public class demo { public static void main(String[] args) { Singleton instance=Singleton.getInstance(); } } class Singleton{ private static Singleton singleton=new Singleton(); private Singleton(){}; public static Singleton getInstance(){ return singleton; } } public class demo { public static void main(String[] args) { Singleton instance=Singleton.getInstance(); Singleton instance2=Singleton.getInstance(); System.out.println(instance2==instance); } }

在这里插入图片描述

4.单例模式中的懒汉模式 class Singleton2{ public static Singleton2 singleton=null; private Singleton2(){}; public static Singleton2 getInstance(){ if(singleton==null){ singleton = new Singleton2(); } return singleton; } } public class demo2 { public static void main(String[] args) { Singleton2 instance=Singleton2.getInstance(); } } 4.1 懒汉模式线程安全问题

线程安全问题指的是多线程环境下,并发的调用 getlnstance 方法,是否可能存在bug. 在这里插入图片描述 通过上述分析,就可以看出,如果多线程运行,有可能会判断出多个null,就会让实例被创建出多份

4.1.1 多线程懒汉模式 synchronized加锁

**加上 synchronized 可以改善这里的线程安全问题.但这样同一时间只有一个线程能进入getSingle方法,此时这个方法内部都是单线程操作,其他线程要进入此方法都需要获取锁 **

synchronized public static Singleton2 getInstance(){ if(singleton==null){ singleton = new Singleton2(); } return singleton; } 4.1.2多线程懒汉模式修改

1.使用双重 if 判定, 降低锁竞争的频率. 2.给 instance 加上了 volatile.

class Singleton2{ public static volatile Singleton2 singleton=null; private Singleton2(){}; public static Singleton2 getInstance(){ //判断要不要加锁 if (singleton == null) { // 初始化对象 synchronized (Singleton2.class) { //判断是否要创建实例 if (singleton == null) { singleton = new Singleton2(); } } } return singleton; } } public class demo2 { public static void main(String[] args) { Singleton2 instance=Singleton2.getInstance(); } }

如果多个线程都去调用这里的getlnstance,就会造成大量的读instance 内存的操作,可能会让编译器把这个读内存操作优化成读寄存器操作,若采用volatile修饰单例对象,volatile可以保证可见性.



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有