JAVA单例模式的几种实现方法

JAVA单例模式的几种实现方法,第1张

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应该如何创建单例类等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zz/9701551.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-01
下一篇 2023-05-01

发表评论

登录后才能评论

评论列表(0条)

保存