`
tianlihu
  • 浏览: 313147 次
  • 性别: Icon_minigender_1
  • 来自: 石家庄
社区版块
存档分类
最新评论

Java 单例模式 工具类

阅读更多
本文版权归作者所有,仅供用来网上学习来用,读者可以收藏,请不要下载到本机和重新发布到其它网站

有觉得可以改进的,请留言,也可加群讨论71326533

我们在实际开发中,会大量采用单例模式。但是我们常常疲于写那几个单调的方法,还可考虑同步的问题,下面就是一个常用的单例模式的写法:
public class Singleton {

	private Singleton() {
	}
	... ...
	... ...
}

为了减少重复的写这些无聊的代码,我写了一个类,用来统一管理这些单例对象
import java.lang.reflect.Constructor;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;

public class SingletonFactory {

	public static final Logger LOG = Logger.getLogger(SingletonFactory.class.getCanonicalName());

	private static final Map<Class<?>, Object> INSTANCE_MAP = Collections.synchronizedMap(new HashMap<Class<?>, Object>());
	private static final Object[] EMPTY_ARGS = new Object[0];

	/**
	 * <pre>
	 * 用此方法有一个前提:
	 * 参数类必须有显示声明的无参构造器或没有任何显示声明的构造器
	 * </pre>
	 */
	public static <T> T getInstance(Class<? extends T> clazz) {
		return getInstance(clazz, EMPTY_ARGS);
	}

	/**
	 * <pre>
	 * 用此方法有两个前提:
	 * 1. 参数数组的项都不能为null
	 * 2. 参数数组的项都不能是简单数据类型
	 * </pre>
	 */
	public static <T> T getInstance(Class<? extends T> clazz, Object... args) {
		Object object = INSTANCE_MAP.get(clazz);
		if (object == null) {
			Class<?>[] parameterTypes = new Class<?>[args.length];
			for (int i = 0; i < args.length; i++) {
				parameterTypes[i] = args[i].getClass();
			}
			return getInstance(clazz, parameterTypes, args);
		}
		return clazz.cast(object);
	}

	/**
	 * <pre>
	 * 用此方法有三个前提:
	 * 1. 两个参数数组同时为null或同时不为null
	 * 2. 两个数组的长度必须相等
	 * 3. parameterTypes如果不空null, 则其各元素不能为null
	 * </pre>
	 */
	public static <T> T getInstance(Class<? extends T> clazz, Class<?>[] parameterTypes, Object[] args) {
		Object object = INSTANCE_MAP.get(clazz);
		if (object == null) { // 检查实例,如是不存在就进行同步代码区
			synchronized (clazz) { // 对其进行锁,防止两个线程同时进入同步代码区
				// 双重检查,非常重要,如果两个同时访问的线程,当第一线程访问完同步代码区后,生成一个实例;当第二个已进入getInstance方法等待的线程进入同步代码区时,也会产生一个新的实例
				if (object == null) {
					try {
						if (parameterTypes != null && args != null) {
							if (parameterTypes.length == args.length) {
								Constructor<?> constructor = clazz.getDeclaredConstructor(parameterTypes);
								constructor.setAccessible(true);
								T instance = clazz.cast(constructor.newInstance(args));
								INSTANCE_MAP.put(clazz, instance);
								return instance;
							} else {
								throw new IllegalArgumentException("参数个数不匹配");
							}
						} else if (parameterTypes == null && args == null) {
							T instance = clazz.newInstance();
							INSTANCE_MAP.put(clazz, instance);
							return instance;
						} else {
							throw new IllegalArgumentException("两个参数数组必须同时为null或同时不为null");
						}
					} catch (Exception e) {
						LOG.log(Level.SEVERE, "创建实例失败", e);
					}
				}
			}
		}
		return null;
	}
}


用法很简单
public class SingletonTest {

	public static void main(String[] args) {
		Singleton obj1 = SingletonFactory.getInstance(Singleton.class);
		Singleton obj2 = SingletonFactory.getInstance(Singleton.class);
		System.out.println(obj1 == obj2);
	}
}

结果:
true

这里统一管理这些单例对象,且单例对象的构造器可以为私有的。如果需要带参数,则需要使用public static <T> T getInstance(Class<? extends T> clazz, Class<?>[] parameterTypes, Object[] args)方法


4
0
分享到:
评论

相关推荐

    Java单例模式与工厂模式简单示例代码

    **单例模式** 是一种限制类实例化次数的设计模式,确保一个类只有一个实例,并提供一个全局访问点。这样做的主要目的是为了节约系统资源,例如数据库连接池、线程池等。在Java中,单例模式的实现通常有几种方法: 1...

    设计模式之单例模式(结合工厂模式)

    单例模式是软件设计模式中的一种经典模式,它保证了类只有一个实例存在,并提供一个全局访问点。在Java等面向对象编程语言中,单例模式常用于管理共享资源,如数据库连接池、线程池或者配置文件等。结合工厂模式,...

    Java单例模式下的MongoDB数据库操作工具类

    Java单例模式下的MongoDB数据库操作工具类 在Java编程中,单例模式是一种常见的设计模式,用于限制类的实例化次数,确保某个类只有一个实例。在数据存储和处理中,MongoDB是一个流行的NoSQL数据库,用于存储和处理...

    java单例模式的登录界面

    **单例模式**是一种常用的软件设计模式,它保证一个类只有一个实例,并提供一个全局访问点。这种模式通常用于控制资源的访问,比如数据库连接、线程池等。 #### 特点: - **唯一性**:确保在整个程序执行期间,只...

    三种工厂设计模式和两种单例模式

    总结来说,工厂设计模式和单例模式都是软件开发中的重要工具,它们有助于提高代码的可读性、可维护性和可扩展性。理解并正确使用这些模式,可以帮助开发者更高效地组织和管理代码,从而构建出更高质量的软件系统。在...

    Java单例模式.docx

    总结来说,单例模式在Java中应用广泛,尤其是在工具类、配置类等场景下。选择合适的实现方式取决于是否需要考虑线程安全以及对性能的要求。对于高并发环境,DCL是较好的选择,因为它既能保证线程安全,又能避免不必...

    Oracle jdbc 单例 工具类

    综上所述,"Oracle jdbc 单例 工具类"主要涉及Oracle数据库的JDBC连接管理,通过单例模式实现连接的高效复用,以及在Java环境中与Oracle数据库交互的基础知识。理解这些概念对于任何使用Java进行数据库开发的程序员...

    Java的单例设计模式

    通过单例模式,我们可以控制类的实例化过程,避免这些问题。 实现单例模式,Java中有几种常见的方法: 1. 饿汉式(静态常量):这是最简单的实现方式,它在类加载时就完成了初始化,因此是线程安全的。代码如下: ...

    工厂模式与单例模式

    其次,单例模式也是一种创建型设计模式,它的特点是确保一个类只有一个实例,并提供一个全局访问点。这种模式常用于配置中心、日志记录、线程池等场景,以节省资源并保证全局一致性。单例模式的实现通常有懒汉式、...

    设计模式——单例模式(懒汉模式)

    单例模式是软件设计模式中的一种经典模式,它保证了类在任何情况下都只有一个实例存在。这个模式在很多场景下非常有用,例如控制全局资源、管理配置信息等。本文将详细探讨单例模式的懒汉式实现,并结合源码进行解析...

    大话设计模式--Singleton(单例模式)

    单例模式的核心思想是确保一个类只有一个实例,并提供一个全局访问点。这种模式主要用于控制类的实例化过程,防止因为多个实例导致的资源浪费或状态不一致问题。在Java、C#等面向对象编程语言中,单例模式有着广泛的...

    Java中的五种实现方法【单例模式】

    在Java编程语言中,单例模式是一种常用的软件设计模式,它的主要目的是确保一个类只有一个实例,并提供一个全局访问点。这种模式在系统中需要频繁创建和销毁对象时,或者对象的创建过程比较昂贵时,特别有用。单例...

    java单例模式使用及注意事项

    Java中的单例模式是一种设计模式,它限制一个类只能创建一个实例,并且提供全局访问点。这种模式在软件开发中非常常见,特别是在需要控制资源、管理配置或创建昂贵对象的场景下。 1. 单例模式的实现方式: - **...

    简单工厂,代理模式,单例模式demo

    在Java中,实现单例模式有多种方式,如饿汉式、懒汉式、双重检查锁定等,每种方式都有其适用场景和优缺点。 结合"源码"标签,理解这些设计模式的最佳方式是通过阅读和分析实际的代码实现。例如,查看一个简单的工厂...

    单例模式----数据库连接池管理类的应用

    单例模式是一种常用的软件设计模式,它保证一个类只有一个实例,并提供一个全局访问点。在IT行业中,尤其是在处理资源密集型任务如数据库连接时,单例模式被广泛应用。数据库连接池就是这种应用的一个典型例子。 ...

    JAVA设计模式

    单例模式确保一个类只有一个实例,并提供一个全局访问点。在Java中,可以使用枚举、双重检查锁定或静态内部类来实现单例,以保证线程安全和防止反序列化创建新实例。 2. **工厂模式(Factory)** 工厂模式提供了...

    JAVA数据库工具类

    在这个特定的场景中,我们关注的是一个基于DBCP(Database Connection Pool)的数据库工具类,它利用了Google工程师Bob Lee提出的懒汉单例模式来构建连接工厂,并将数据库连接与当前线程绑定,以优化资源管理和防止...

    java设计模式之——单例模式

    单例模式是软件设计模式中的一种经典模式,其主要目的是控制类的实例化过程,确保在任何情况下,一个类只有一个实例存在。这种模式通常用于管理共享资源或者全局配置,例如数据库连接池、线程池、日志服务等。在Java...

Global site tag (gtag.js) - Google Analytics