创建型---单例模式

举报
斌哥来了 发表于 2021/07/29 10:28:01 2021/07/29
【摘要】 // 数据库类会对 `getInstance (获取实例) ` 方法进行定义以让客户端在程序各处 // 都能访问相同的数据库连接实例。 class Database is // 保存单例实例的成员变量必须被声明为静态类型。 private static field instance: Database // 单例的构造函数必须永远是私有类型,以防止使用 `...













// 数据库类会对 `getInstance (获取实例) ` 方法进行定义以让客户端在程序各处

// 都能访问相同的数据库连接实例。

class Database is

// 保存单例实例的成员变量必须被声明为静态类型。

private static field instance: Database


// 单例的构造函数必须永远是私有类型,以防止使用 `new` 运算符直接调用构

// 造方法。

private constructor Database() is

// 部分初始化代码(例如到数据库服务器的实际连接)。

// ...


// 用于控制对单例实例的访问权限的静态方法。

public static method getInstance() is

if (Database.instance == null) then

acquireThreadLock() and then

// 确保在该线程等待解锁时,其他线程没有初始化该实例。

if (Database.instance == null) then

Database.instance = new Database()

return Database.instance


// 最后,任何单例都必须定义一些可在其实例上执行的业务逻辑。

public method query(sql) is

// 比如应用的所有数据库查询请求都需要通过该方法进行。因此,你可以

// 在这里添加限流或缓冲逻辑。

// ...


class Application is

method main() is

Database foo = Database.getInstance()

foo.query("SELECT ...")

// ...

Database bar = Database.getInstance()

bar.query("SELECT ...")

// 变量 `bar` `foo` 中将包含同一个对象。









基础单例(单线程)

实现一个粗糙的单例非常简单   你仅需隐藏构造函数并实现一个静态的构建方法即可

Singleton.java:   单例

public final class Singleton {

private static Singleton instance ;

public String value ;


private Singleton ( String value ) {

// The following code emulates slow initialization.

try {

Thread . sleep ( 1000 );

} catch ( InterruptedException ex ) {

ex . printStackTrace ();

}

this . value = value ;

}


public static Singleton getInstance ( String value ) {

if ( instance == null ) {

instance = new Singleton ( value );

}

return instance ;

}

}

DemoSingleThread.java:   客户端代码

public class DemoSingleThread {

public static void main ( String [] args ) {

System . out . println ( "If you see the same value, then singleton was reused (yay!)" + "\n" +

"If you see different values, then 2 singletons were created (booo!!)" + "\n\n" +

"RESULT:" + "\n" );

Singleton singleton = Singleton . getInstance ( "FOO" );

Singleton anotherSingleton = Singleton . getInstance ( "BAR" );

System . out . println ( singleton . value );

System . out . println ( anotherSingleton . value );

}

}


OutputDemoSingleThread.txt:   执行结果

If you see the same value, then singleton was reused (yay!)

If you see different values, then 2 singletons were created (booo!!)


RESULT:


FOO

FOO



基础单例(多线程)

  Singleton.java:   单例


public final class Singleton {

private static Singleton instance ;

public String value ;


private Singleton ( String value ) {

// The following code emulates slow initialization.

try {

Thread . sleep ( 1000 );

} catch ( InterruptedException ex ) {

ex . printStackTrace ();

}

this . value = value ;

}


public static Singleton getInstance ( String value ) {

if ( instance == null ) {

instance = new Singleton ( value );

}

return instance ;

}

}

DemoMultiThread.java:   客户端代码

public class DemoMultiThread {

public static void main ( String [] args ) {

System . out . println ( "If you see the same value, then singleton was reused (yay!)" + "\n" +

"If you see different values, then 2 singletons were created (booo!!)" + "\n\n" +

"RESULT:" + "\n" );

Thread threadFoo = new Thread ( new ThreadFoo ());

Thread threadBar = new Thread ( new ThreadBar ());

threadFoo . start ();

threadBar . start ();

}


static class ThreadFoo implements Runnable {

@Override

public void run () {

Singleton singleton = Singleton . getInstance ( "FOO" );

System . out . println ( singleton . value );

}

}


static class ThreadBar implements Runnable {

@Override

public void run () {

Singleton singleton = Singleton . getInstance ( "BAR" );

System . out . println ( singleton . value );

}

}

}


OutputDemoMultiThread.txt:   执行结果

If you see the same value, then singleton was reused (yay!)

If you see different values, then 2 singletons were created (booo!!)


RESULT:


FOO

BAR



采用延迟加载的线程安全单例

Singleton.java:   单例

public final class Singleton {

// The field must be declared volatile so that double check lock would work

// correctly.

private static volatile Singleton instance ;


public String value ;


private Singleton ( String value ) {

this . value = value ;

}


public static Singleton getInstance ( String value ) {

// The approach taken here is called double-checked locking (DCL). It

// exists to prevent race condition between multiple threads that may

// attempt to get singleton instance at the same time, creating separate

// instances as a result.

//

// It may seem that having the `result` variable here is completely

// pointless. There is, however, a very important caveat when

// implementing double-checked locking in Java, which is solved by

// introducing this local variable.

//

// You can read more info DCL issues in Java here:

// https://refactoring.guru/java-dcl-issue

Singleton result = instance ;

if ( result != null ) {

return result ;

}

synchronized ( Singleton . class ) {

if ( instance == null ) {

instance = new Singleton ( value );

}

return instance ;

}

}

}

DemoMultiThread.java:   客户端代码

public class DemoMultiThread {

public static void main ( String [] args ) {

System . out . println ( "If you see the same value, then singleton was reused (yay!)" + "\n" +

"If you see different values, then 2 singletons were created (booo!!)" + "\n\n" +

"RESULT:" + "\n" );

Thread threadFoo = new Thread ( new ThreadFoo ());

Thread threadBar = new Thread ( new ThreadBar ());

threadFoo . start ();

threadBar . start ();

}


static class ThreadFoo implements Runnable {

@Override

public void run () {

Singleton singleton = Singleton . getInstance ( "FOO" );

System . out . println ( singleton . value );

}

}


static class ThreadBar implements Runnable {

@Override

public void run () {

Singleton singleton = Singleton . getInstance ( "BAR" );

System . out . println ( singleton . value );

}

}

}

OutputDemoMultiThread.txt:   执行结果


If you see the same value, then singleton was reused (yay!)

If you see different values, then 2 singletons were created (booo!!)


RESULT:


BAR

BAR


【版权声明】本文为华为云社区用户原创内容,未经允许不得转载,如需转载请自行联系原作者进行授权。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。