JAVA
单例模式的几种实现方法
1饿汉式单例类
package
patternsingleton;
//
饿汉式单例类
在类初始化时,已经自行实例化
public
class
Singleton1
{
//
私有的默认构造子
private
Singleton1()
{}
//
已经自行实例化
private
static
final
Singleton1
single
=
new
Singleton1();
//
静态工厂方法
public
static
Singleton1
getInstance()
{
return
single;
}
}
2
懒汉式单例类
package
patternsingleton;
//
懒汉式单例类
在第一次调用的时候实例化
public
class
Singleton2
{
//
私有的默认构造子
private
Singleton2()
{}
//
注意,这里没有
final
private
static
Singleton2
single;
//
只实例化一次
static
{
single
=
new
Singleton2();
}
//
静态工厂方法
public
synchronized
static
Singleton2
getInstance()
{
if
(single
==
null
)
{
single
=
new
Singleton2();
}
return
single;
}
}
在上面给出懒汉式单例类实现里对静态工厂方法使用了同步化,以处理多线程环境。有些设计师在这里建议使用所谓的
"
双重检查成例
"
必须指出的是,
"
双重检查成例
"
不可以在
Java
语言中使用。不十分熟悉的读者,可以看看后面给出的小节。
同
样,由于构造子是私有的,因此,此类不能被继承。饿汉式单例类在自己被加载时就将自己实例化。即便加载器是静态的,在饿汉
式单例类被加载时仍会将自己实例化。单从资源利用效率角度来讲,这个比懒汉式单例类稍差些。从速度和反应时间角度来讲,
则
比懒汉式单例类稍好些。然而,懒汉式单例类在实例化时,必须处
理好在多个线程同时首次引用此类时的访问限制问题,特别是当单例类作为资源控制器,在实例化时必然涉及资源初始化,而资源
初始化很有可能耗费时间。这意味着出现多线程同时首次引用此类的机率变得较大。
饿汉式单例类可以在
Java
语言内实现,
但不易在
C++
内实现,因为静态初始化在
C++
里没有固定的顺序,因而静态的
m_instance
变量的初始化与类的加载顺序没有保证,可能会出问题。这就是为什么
GoF
在提出单例类的概念时,举的例子是懒
汉式的。他们的书影响之大,以致
Java
语言中单例类的例子也大多是懒汉式的。实际上,本书认为饿汉式单例类更符合
Java
语
言本身的特点。
3
登记式单例类
package
patternsingleton;
import
javautilHashMap;
import
javautilMap;
//
登记式单例类
//
类似
Spring
里面的方法,将类名注册,下次从里面直接获取。
public
class
Singleton3
{
private
static
Map<String,Singleton3>
map
=
new
HashMap<String,Singleton3>();
static
{
Singleton3
single
=
new
Singleton3();
mapput(singlegetClass()getName(),
single);
}
//
保护的默认构造子
protected
Singleton3(){}
//
静态工厂方法
,
返还此类惟一的实例
public
static
Singleton3
getInstance(String
name)
{
if
(name
==
null
)
{
name
=
Singleton3
class
getName();
Systemoutprintln("name
==
null"+"--->name="+name);
}
if
(mapget(name)
==
null
)
{
try
{
mapput(name,
(Singleton3)
ClassforName(name)newInstance());
}
catch
(InstantiationException
e)
{
eprintStackTrace();
}
catch
(IllegalAccessException
e)
{
eprintStackTrace();
}
catch
(ClassNotFoundException
e)
{
eprintStackTrace();
}
}
return
mapget(name);
}
//
一个示意性的商业方法
public
String
about()
{
return
"Hello,
I
am
RegSingleton";
}
public
static
void
main(String[]
args)
{
Singleton3
single3
=
Singleton3getInstance(
null
);
Systemoutprintln(single3about());
}
}
public class SingletonClass{
//私有的构造方法,确保不会在外部创建实例
private SingletonClass(){ }
//返回一个SingletonClass类型的对象(通过调用SingletonClassInstance类)
public static SingletonClass getInstance(){
return SingletonClassInstanceinstance;
}
//内部的一个私有静态类,其中包含了一个静态属性instance
private static class SingletonClassInstance{
//因为instance是static的,所以它不会被构造多次
private static final SingletonClass instance = new SingletonClass();
}
}
一 什么是单例模式
因程序需要,有时我们只需要某个类同时保留一个对象,不希望有更多对象,此时,我们则应考虑单例模式的设计。
二 单例模式的特点
1 单例模式只能有一个实例。
2 单例类必须创建自己的唯一实例。
3 单例类必须向其他对象提供这一实例。
三单例模式的实现
懒汉模式
public class SingletonDemo {
private static SingletonDemo instance;
private SingletonDemo(){
}
public static SingletonDemo getInstance(){
if(instance==null){
instance=new SingletonDemo();
}
return instance;
}
}
2 线程安全的懒汉模式
public class SingletonDemo {
private static SingletonDemo instance;
private SingletonDemo(){
}
public static synchronized SingletonDemo getInstance(){
if(instance==null){
instance=new SingletonDemo();
}
return instance;
}
}
3 饿汉模式
public class SingletonDemo {
private static SingletonDemo instance=new SingletonDemo();
private SingletonDemo(){
}
public static SingletonDemo getInstance(){
return instance;
}
}
4 静态类内部加载
public class SingletonDemo {
private static class SingletonHolder{
private static SingletonDemo instance=new SingletonDemo();
}
private SingletonDemo(){
Systemoutprintln("Singleton has loaded");
}
public static SingletonDemo getInstance(){
return SingletonHolderinstance;
}
}
5双重校验锁法
public class SingletonDemo {
private volatile static SingletonDemo instance;
private SingletonDemo(){
Systemoutprintln("Singleton has loaded");
}
public static SingletonDemo getInstance(){
if(instance==null){
synchronized (SingletonDemoclass){
if(instance==null){
instance=new SingletonDemo();
}
}
}
return instance;
}
}
首先 这个不能用Singleton解决
因为需要解决的是唯一进程的问题
java可以使用文件锁或者绑定端口来解决这个问题
1文件锁是在程序运行同时每隔一段时间向一个文件写入当前时间
如果再次启动该程序 会先判断写入时间的文件 如果和当前时间间隔
小于设定的时间间隔 则视为该进程正在运行 否则可以启动
2绑定端口是在程序中绑定一个固定端口号 如果再次启动该程序
首先判断该端口是否正在被监听 如果未被监听 则可以启动
java不像vc那样方便去取系统进程句柄判断程序是否已经运行
以上就是关于JAVA单例模式的几种实现方法全部的内容,包括:JAVA单例模式的几种实现方法、java中怎么写一个单例的例子,看了许多,就是不会写.、Java EE应该如何创建单例类等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)