创建型---单例模式
// 数据库类会对 `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
- 点赞
- 收藏
- 关注作者
评论(0)