标签:图片 完成 静态方法 rgs 数据库 访问 饿汉式 单例设计模式 数据
单例模式,就是采取一定的方法保证在整个的软件系统中,对某个类只能存在一个对象实例,并且该类只提供一个取得其对象实例的方法。
1)饿汉式(静态常量)
2)饿汉式 (静态代码块)
3)懒汉式(线程不安全)
4)懒汉式(线程安全,同步方法)
5)双重检查
6)静态内部类
7)枚举
1)创建静态常量实例
2)构造器私有化(防止new)
3)向外暴露一个静态的公共方法。
4)代码实现
/**
* 饿汉式(静态常量)
*/
public class Singleton1 {
// 1.创建静态常量实例
private final static Singleton1 instance = new Singleton1();
//2. 构造函数私有化
private Singleton1(){
}
//3.获取实例对象
public static Singleton1 getInstance(){
return instance;
}
}
优缺点说明
1)优点:写法简单,在类装载的时候就完成了实例化。避免了线程同步问题。
2)缺点:在类装载时就完成实例化,没有达到懒加载的效果。如果从始至终从未使用过这个实例,则会造成内存浪费。
1)静态代码块中,创建单例对象。
2)构造函数私有化
3)提供公有的静态方法,返回实例对象
/**
* 饿汉式(静态常量)
*/
public class SingletonTest2 {
public static void main(String[] args) {
//测试
Singleton instance1 = Singleton.getInstance();
Singleton instance2 = Singleton.getInstance();
System.out.println(instance1 == instance2); // true
System.out.println("instance1.hashCode=" + instance1.hashCode());
System.out.println("instance2.hashCode=" + instance2.hashCode());
}
}
class Singleton{
// 1.静态代码块中,创建单例对象
private static Singleton instance;
static{
instance = new Singleton();
}
//2. 构造函数私有化
private Singleton(){
}
//3.获取实例对象
public static Singleton getInstance(){
return instance;
}
}
分析:
1)和饿汉式(静态常量)是一样的,只不过将类实例化的过程放在了静态代码块中。
思路:提供一个静态的公有方法,当使用该方法时,才去创建实例对象
/**
* 懒汉式(线程不安全)
*/
public class SingletonTest3 {
public static void main(String[] args) {
//测试
Singleton instance1 = Singleton.getInstance();
Singleton instance2 = Singleton.getInstance();
System.out.println(instance1 == instance2); // true
System.out.println("instance1.hashCode=" + instance1.hashCode());
System.out.println("instance2.hashCode=" + instance2.hashCode());
}
}
class Singleton{
private static Singleton instance;
private Singleton(){
}
//3.获取实例对象
public static Singleton getInstance(){
if(instance==null){
instance = new Singleton();
}
return instance;
}
}
优缺点说明:
1)起到了懒加载的效果,但只能在单线程下使用。
2)如果在多线程下,一个线程进入了if(instance == null)语句块,还未来得及往下执行,另一个线程也通过了这个判断语句,这时就会产生多个实例。
3)结论:在实际开发中,不要使用这种方式
/**
* 懒汉式(线程安全,同步方法)
*/
public class SingletonTest4 {
public static void main(String[] args) {
//测试
Singleton instance1 = Singleton.getInstance();
Singleton instance2 = Singleton.getInstance();
System.out.println(instance1 == instance2); // true
System.out.println("instance1.hashCode=" + instance1.hashCode());
System.out.println("instance2.hashCode=" + instance2.hashCode());
}
}
class Singleton{
private static Singleton instance;
private Singleton(){
}
//3.获取实例对象
public static synchronized Singleton getInstance(){
if(instance==null){
instance = new Singleton();
}
return instance;
}
}
优缺点分析:
1)解决了线程安全问题。
2)方法进行同步效率太低,每个线程想要获得实例时,必须等待其余线程执行完。
3)结论:不推荐使用
/**
* 双重检查
*/
public class SingletonTest5 {
public static void main(String[] args) {
//测试
Singleton instance1 = Singleton.getInstance();
Singleton instance2 = Singleton.getInstance();
System.out.println(instance1 == instance2); // true
System.out.println("instance1.hashCode=" + instance1.hashCode());
System.out.println("instance2.hashCode=" + instance2.hashCode());
}
}
class Singleton{
private static Singleton instance;
private Singleton(){
}
//3.获取实例对象
public static Singleton getInstance(){
if(instance==null){
synchronized(Singleton.class){
if(instance == null){
instance = new Singleton();
}
}
}
return instance;
}
}
优缺点分析:
1)双重检查概念是多线程开发中经常使用到的,即保证线程安全,又避免反复进行方法同步。
2)线程安全,符合懒加载,效率较高。
3)推荐使用
/**
* 静态内部类
*/
public class SingletonTest6 {
public static void main(String[] args) {
//测试
Singleton instance1 = Singleton.getInstance();
Singleton instance2 = Singleton.getInstance();
System.out.println(instance1 == instance2); // true
System.out.println("instance1.hashCode=" + instance1.hashCode());
System.out.println("instance2.hashCode=" + instance2.hashCode());
}
}
class Singleton{
private Singleton(){
}
private static class SingletonInstance{
public final static Singleton INSTANCE = new Singleton();
}
public static Singleton getInstance(){
return SingletonInstance.INSTANCE;
}
}
优缺点分析:
1)采用了类装载机制保证初始化实例时只有一个线程。
2)静态内部类方式在Singleton类被装载时并不会立即实例化,而是在需要实例化时调用getInstance方法才会装载SingletonInstance类,完成instance实例化。
3)类的静态属性只会在第一次加载类时初始化。JVM帮我们保证了线程的安全性,在类初始化时,别的线程无法进入。
4)推荐使用
/**
* 枚举
*/
public class SingletonTest7 {
public static void main(String[] args) {
//测试
Singleton instance1 = Singleton.INSTANCE;
Singleton instance2 = Singleton.INSTANCE;
System.out.println(instance1 == instance2); // true
System.out.println("instance1.hashCode=" + instance1.hashCode());
System.out.println("instance2.hashCode=" + instance2.hashCode());
}
}
enum Singleton{
INSTANCE;
}
优缺点说明:
1)借助枚举实现单例模式。不进避免多线程同步问题,还能防止反序列化重新创建新的对象。
2)推荐使用
单例模式在JDK应用的源码分析
1)jdk中,java.lang.Runtime就是经典的单例模式(饿汉式)
2)代码分析
1)单例模式保证了系统内存中该类只存在一个对象,节省了系统资源。对于一些需要频繁创建销毁的对象,单例模式可以提高性能
2)当想实例化一个单例类时,必须使用相应的获取对象的方法,而不是new
3)单例模式使用场景:需要频繁创建和销毁的对象、创建对象耗时过多或资源耗费多(重量级对象)、工具类对象、频繁访问数据库或文件的对象(比如数据源、session工厂)
标签:图片 完成 静态方法 rgs 数据库 访问 饿汉式 单例设计模式 数据
原文地址:https://www.cnblogs.com/chao-zjj/p/11273741.html