首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 软件管理 > 软件架构设计 >

温习单例模式

2012-11-09 
复习单例模式?基本的单例模式: ?public class SingletonTest{private static SingletonTestinstancepriva

复习单例模式

?基本的单例模式:

?

public class SingletonTest{private static SingletonTestinstance;private SingletonTest() {}public static SingletonTest getInstance() {if (instance == null) {instance = new SingletonTest();}return instance;}}

?调用

public class Main {public static void main(String[] args) {SingletonTest singlonTest=SingletonTest.getInstance();}

?但是 这样在多线程模式下可能出现多实例的现象,模拟一下

public class Main {??static Set instanceSet =Collections.synchronizedSet(new HashSet());??public static void main(String[] args) {??long start = System.currentTimeMillis();?? Thread threads[] = new Thread[1000] ;??for (int i = 0; i < 1000; i++) {??threads[i] = new MyThread();
??}??for (int i = 0; i < 1000; i++) {???threads[i].start();?//??System.out.println(threads[i].getName());??}??long end = System.currentTimeMillis();??System.out.println("耗时:" + (end - start) + "ms");??System.out.println(instanceSet.size());??for(Iterator i=instanceSet.iterator();i.hasNext();){???System.out.println(i.next());??}?}}
class MyThread extends Thread {?public void run() {??SingletonTest a = SingletonTest.getInstance();
??Main.instanceSet.add(a);
?}}

?观察输出可以看到产生了多个实例。

防止这种多线程产生多实例的方法有:

1.方法前加 synchronized

public class SingletonTest{private static SingletonTest instance;private SingletonTest() {System.out.println("create instance");}public static synchronized SingletonTest getInstance() {if (instance == null) {instance = new SingletonTest();}return instance;}}

?这种效率较低 只能同时有一个线程调用getInstance?? 其实真正只要在? instance=new SingletonTest()同步。

?2.在产生实例的地方加同步

public class SingletonTest {private static SingletonTest instance = null;private SingletonTest() {System.out.println("create instance");}public static SingletonTest getInstance() {if(instance==null){             synchronized(SingletonTest.class){instance=new SingletonTest();}}return instance;}}

?这样处理有多线程时还是会产生多个实例

?

?3.双重锁

?

public class SingletonTest {private static SingletonTest instance = null;private SingletonTest() {System.out.println("create instance");}public static SingletonTest getInstance() {if(instance==null){synchronized(SingletonTest.class){if(instance==null){instance=new SingletonTest();}}}return instance;}}

?这也不是完美无缺的,在java的内存模型里有可能出现多个实例

instance = new Singleton();java代码的过程可解释如下 3个步骤?

?1??mem = allocate();? ?? ?? ?? ?//Allocate memory for Singleton object. % z$ S, _' s. D% A
2??instance = mem;? ?? ?? ?? ???//Note that instance is now non-null, but?
??????????????????????//has not been initialized. * X% ]1 @( c+ T4 H" ~, I
3??ctorSingleton(instance);? ?? ?//Invoke constructor for Singleton passing?instance. ! Z( m??

    Thread 1 enters the getInstance() method.

    Thread 1 enters the synchronized block at //1 because instance is null.

    Thread 1 proceeds to //3 and makes instance non-null, but before the constructor executes.

    Thread 1 is preempted by thread 2.

    Thread 2 checks to see if instance is null. Because it is not, thread 2 returns the instance reference to a fully constructed, but partially initialized, Singleton object.

    Thread 2 is preempted by thread 1.

    Thread 1 completes the initialization of the Singleton object by running its constructor and returns a reference to it.

?

?

4.早期初始化

public class SingletonTest{private static SingletonTest instance = new SingletonTest();private SingletonTest() {System.out.println("create instance");}public static SingletonTest getInstance() {return instance;}}

?

参考:http://www.ibm.com/developerworks/library/j-dcl.html?S_TACT=105AGX52&S_CMP=cn-a-j

热点排行