[心缘地方]同学录
首页 | 功能说明 | 站长通知 | 最近更新 | 编码查看转换 | 代码下载 | 常见问题及讨论 | 《深入解析ASP核心技术》 | 王小鸭自动发工资条VBA版
登录系统:用户名: 密码: 如果要讨论问题,请先注册。

[备忘]单例模式的效率问题……

上一篇:[备忘]SQL中LIKE需要Escape的字符都有哪些哇
下一篇:[转帖]语法分析引擎基类C#版

添加日期:2010/8/10 17:24:20 快速返回   返回列表 阅读3753次
一直想不开的一个事……
 
单例模式是整个应用中只有一个这个类的实例,
 
那么A用户访问到它,调用它的aaa()方法
 
B也访问它,调用aaa()方法,
 
C也是,D也是……
 
那么,ABCD是否需要排队呢?
==================================
就想一个车,调用它的go()方法
ABCD几个人是否需要排队,轮流开?
还是可以4个人一起上……
==================================
即单例模式的效率问题……
 
大家批批……




-------------------------------------
打吧,谁赢了谁先上。或者谁后台硬谁先上。

-------------------------------------
我觉得这个是进程间同步的问题,独占式资源就得排,非独占式资源随意~

-------------------------------------
我觉得这个是进程间同步的问题,独占式资源就得排,非独占式资源随意~[/quote]
那么,调用者如何知道被调用的是否是独占性的?
换句话说,
假设类实例本身是无状态的,那么对一个方法的调用可以同时进行?
同时读一个变量很好理解,同时调用一个方法呢?
类实例是有状态的,还是无状态的,这个谁来判断呢?

-------------------------------------
我觉得车的比喻不正确。
应该是大锅饭更接近,一锅饭大家一起吃,大家吃的都是一样的东西。没有谁先谁后。

-------------------------------------
[quote]我觉得车的比喻不正确。
应该是大锅饭更接近,一锅饭大家一起吃,大家吃的都是一样的东西。没有谁先谁后。[/quote]
那,除非说,单例模式的类,本身都是无状态的,那就好理解了。
如果可以是有状态的,那么必须自己解决同步的问题。难道是这样?

-------------------------------------
[quote]那,除非说,单例模式的类,本身都是无状态的,那就好理解了。
如果可以是有状态的,那么必须自己解决同步的问题。难道是这样?[/quote]
这些状态是大家共用的,可以说第一次有值后很少会变。
所以也不用去考虑同步问题。
如果需要考虑同步问题,那就只能自己解决了。
不过,个人认为单列类不应该当作普通类来使用,如果状态频繁的变,那就不应该是单列的。

-------------------------------------
单例模式应该有特殊的用途吧,王老板举的例子应该不适合吧。
就类似于现实中去看电影,屏幕就是一个单例模式,不可能到了影院一人抱一个显示器吧,而播放的内容就可以看作具体的方法,情节内容不同。
我之前曾在家园的论坛上发过类似的问题。好像struts框架中,action就可以看成单例模式吧,而对应的dao层就不能设计成单例的,因为要通过这一个action实例频繁调用dao的各种方法。

-------------------------------------
单例模式貌似是为特殊状况准备的:
1,想保证某个特定的类的对象实例绝对只有1个时
2,想在程序上表达出对象实例只有1个时

getInstance() 返回的值是静态的,应该在数据区吧,也只有一个,不在堆空间里。。

-------------------------------------
获取对象实例时不需要排队,随到随得。
但该单例对象要处理线程同步问题,以免多线程调用出现问题~

-------------------------------------

-------------------------------------
现在的理解:
不加同步关键字,方法可以同时调用。
加了,就得排队。

-------------------------------------
个人感觉单例模式应该排队,不过一办这样的东西都是很快就完成了,抽空写个死循环的单例模式试验下就知道了。

-------------------------------------
上学时记得老师说过,单例频繁修改数据就得加线程安全关键字,可见调用单例并不需要排队

-------------------------------------
能否给解释一下 :
整个应用中只有一个这个类的实例, 
-》也就是说这个应用启动之后在内存中,这个实例只被使用一次。
那么下面的问题就是 那种状态下 a用户 b用户。。。 都同时调用这个内存呢?
还有就是发生了同时调用的时候,每个用户与这个应用产生交互,肯定都是在使用同一个线程不? 
如果线程不一样,那岂不就是操作系统的问题了?
不好意思,理解不深

-------------------------------------
[quote]能否给解释一下 :
整个应用中只有一个这个类的实例, 
-》也就是说这个应用启动之后在内存中,这个实例只被使用一次。
那么下面的问题就是 那种状态下 a用户 b用户。[/quote]
如果是在一个线程中调用单例对象的话,那肯定就不会出什么问题了~
进程的代码区应该是所有线程共享的(数据区是分别的),就算不用单例模式,代码在进程的内存中也只有一份儿~

-------------------------------------
上代码啦:
单例:
public  class  Singel {
        
        private Singel(){}
        
        private static Singel ins;
        
        
        public static Singel getInstance(){
                if(ins == null){
                        ins =  new Singel();
                }
                return ins;
        }
        
        //public synchronized  void  a(Class thClass){
        public    void  a(Class thClass){
                for(int i = 0 ; i < 1000000 ; i ++){
                        System.out.println(thClass.getName());
                }
        }
}

测试:
public class Test {
        public static void main(String args[]){
                Thread t1 = new MyThread1();
                Thread t2 = new MyThread2();
                t1.start();
                t2.start();
        }
        
}

class MyThread1 extends Thread{
        public void run(){
                Singel s = Singel.getInstance();
                s.a(this.getClass());
        }
}

class MyThread2 extends Thread{
        public void run(){
                Singel s = Singel.getInstance();
                s.a(this.getClass());
        }
}

结果:
MyThread2
MyThread1
MyThread2
MyThread1
MyThread2
MyThread1

感谢诸位,彻底了解单例啦

-------------------------------------
[quote]现在的理解:
不加同步关键字,方法可以同时调用。
加了,就得排队。[/quote]
我觉得关键在于能不能保证操作的原子性,如果不加线程同步也可以保证操作的原子性,就没有必要加锁。例如写log,或者获取系统时间但是不更改这种操作。
而如果不能保证原子性,例如对单例的操作中,要求单例的状态不发生意外的变化,或者单例的多个方法存在顺序上的相互依赖的话,就只能加锁,或者不采用单例模式。

-------------------------------------
[quote]上代码啦:
单例:
public  class  Singel {
        
        private Singel(){}
        
        private static Singel ins;
        
        
        public static Singel getInstance(){
                if(ins == null){
[/quote]
加了同步呢?
22222222
2222222222
222222222
11111111
11111111
这样?

-------------------------------------
[quote]加了同步呢?
22222222
2222222222
222222222
11111111
11111111
这样?[/quote]
是  有点困惑的是为什么是先2后1

-------------------------------------
[quote]是  有点困惑的是为什么是先2后1[/quote]
就是线程的原因了,线程被执行的时机是不定的。
5个线程未同步的结果:
===========================
MyThread2
MyThread2
MyThread2
MyThread2
MyThread2
MyThread2
MyThread2
MyThread2
MyThread2
MyThread2
MyThread2
MyThread2
MyThread2
MyThread2
MyThread2
MyThread2
MyThread2
MyThread2
MyThread2
MyThread2
MyThread2
MyThread2
MyThread2
MyThread2
MyThread2
MyThread2
MyThread2
MyThread2
MyThread2
MyThread2
MyThread2
MyThread2
MyThread2
MyThread2
MyThread2
MyThread2
MyThread2
MyThread2
MyThread2
MyThread2
MyThread2
MyThread2
MyThread2
MyThread2
MyThread2
MyThread2
MyThread2
MyThread1
MyThread3
MyThread4
MyThread5
MyThread2
MyThread1
MyThread3
MyThread4
MyThread5
MyThread2
MyThread3
MyThread4
MyThread5
MyThread2
MyThread3
MyThread4
MyThread5
MyThread1
MyThread3
MyThread4
MyThread5
MyThread1
MyThread2
MyThread3
MyThread4
MyThread1
MyThread2
MyThread3
MyThread4
MyThread1
MyThread2
MyThread3
MyThread4
MyThread1
MyThread2
MyThread3
MyThread4
MyThread1
MyThread2
MyThread3
MyThread4
MyThread5
MyThread2
MyThread3
MyThread4
MyThread5
MyThread1
MyThread2
MyThread3
MyThread5
MyThread4
MyThread1
MyThread2
MyThread3
MyThread5
MyThread4
MyThread1
MyThread2
MyThread3
MyThread5
MyThread4
MyThread1
MyThread2
MyThread3
MyThread5
MyThread4
MyThread1
MyThread2
MyThread3
MyThread4
MyThread5
MyThread2
MyThread3
MyThread4
MyThread5
MyThread1
MyThread2
MyThread3
MyThread5
MyThread1
MyThread2
MyThread3
MyThread5
MyThread1
MyThread2
MyThread3
MyThread5
MyThread1
MyThread2
MyThread3
MyThread5
MyThread1
MyThread2
MyThread3
MyThread4
MyThread1
MyThread2
MyThread5
MyThread4
MyThread3
MyThread1
MyThread5
MyThread4
MyThread3
MyThread1
MyThread5
MyThread4
MyThread3
MyThread1
MyThread5
MyThread4
MyThread2
MyThread1
MyThread5
MyThread4
MyThread2
MyThread1
MyThread5
MyThread3
MyThread2
MyThread1
MyThread4
MyThread3
MyThread2
MyThread5
MyThread4
MyThread3
MyThread2
MyThread5
MyThread4
MyThread3
MyThread2
MyThread5
MyThread4
MyThread3
MyThread1
MyThread5
MyThread4
MyThread3
MyThread1
MyThread5
MyThread4
MyThread2
MyThread1
MyThread3
MyThread5
MyThread2
MyThread1
MyThread3
MyThread5
MyThread2
MyThread1
MyThread3
MyThread5
MyThread2
MyThread1
MyThread3
MyThread5
MyThread2
MyThread4
MyThread3
MyThread5
MyThread2
MyThread4
MyThread3
MyThread5
MyThread1
MyThread4
MyThread2
MyThread3
MyThread1
MyThread4
MyThread2
MyThread3
MyThread1
MyThread4
MyThread2
MyThread3
MyThread1
MyThread4
MyThread2
MyThread3
MyThread1
MyThread5
MyThread2
MyThread3
MyThread1
MyThread5
MyThread2
MyThread3
MyThread4
MyThread1
MyThread5
MyThread2
MyThread4
MyThread1
MyThread5
MyThread2
MyThread4
MyThread1
MyThread5
MyThread2
MyThread4
MyThread1
MyThread3
MyThread2
MyThread4
MyThread1
MyThread3
MyThread2
MyThread4
MyThread1
MyThread3
MyThread2
MyThread5
MyThread4
MyThread3
MyThread1
MyThread5
MyThread4
MyThread3
MyThread1
MyThread5
MyThread4
MyThread3
MyThread1
MyThread5
MyThread4
MyThread2
MyThread1
MyThread5
MyThread4
MyThread2
MyThread1
MyThread5
MyThread4
MyThread2
MyThread1
MyThread3
MyThread5
MyThread2
MyThread4
MyThread3
MyThread5
MyThread2
MyThread4
MyThread3
MyThread5
MyThread2
MyThread4
MyThread3
MyThread5
MyThread1
MyThread4
MyThread3
MyThread5
MyThread1
MyThread4
MyThread3
MyThread2
MyThread1
MyThread4
MyThread5
MyThread2
MyThread1
MyThread3
MyThread5
MyThread1
MyThread3
MyThread5
MyThread1
MyThread3
MyThread5
MyThread4
MyThread3
MyThread5
MyThread4
MyThread3
MyThread5
MyThread4
MyThread3
MyThread1
MyThread4
MyThread5
MyThread3
MyThread1
MyThread4
MyThread5
MyThread3
MyThread1
MyThread4
MyThread5
MyThread3
MyThread1
MyThread5
MyThread3
MyThread1
MyThread5
MyThread3
MyThread4
MyThread5
MyThread3
MyThread4
MyThread1
MyThread5
MyThread4
MyThread1
MyThread5
MyThread4
MyThread1
MyThread5
MyThread4
MyThread1
MyThread5
MyThread4
MyThread1
MyThread5
MyThread3
MyThread1
MyThread5
MyThread3
MyThread4
MyThread1
MyThread3
MyThread4
MyThread1
MyThread3
MyThread4
MyThread1
MyThread3
MyThread4
MyThread5
MyThread1
MyThread3
MyThread4
MyThread5
MyThread1
MyThread4
MyThread5
MyThread3
MyThread1
MyThread5
MyThread3
MyThread1
MyThread5
MyThread3
MyThread1
MyThread5
MyThread3
MyThread1
MyThread4
MyThread3
MyThread1
MyThread4
MyThread3
MyThread1
MyThread4
MyThread5
MyThread3
MyThread4
MyThread5
MyThread3
MyThread4
MyThread5
MyThread3
MyThread4
MyThread5
MyThread3
MyThread1
MyThread5
MyThread3
MyThread1
MyThread5
MyThread3
MyThread1
MyThread4
MyThread5
MyThread1
MyThread3
MyThread4
MyThread5
MyThread1
MyThread3
MyThread4
MyThread5
MyThread1
MyThread3
MyThread4
MyThread5
MyThread3
MyThread4
MyThread5
MyThread3
MyThread1
MyThread5
MyThread3
MyThread1
MyThread4
MyThread5
MyThread1
MyThread4
MyThread5
MyThread1
MyThread4
MyThread5
MyThread1
MyThread4
MyThread5
MyThread1
MyThread4
MyThread5
MyThread3
MyThread4
MyThread5
MyThread3
MyThread1
MyThread4
MyThread3
MyThread1
MyThread4
MyThread3
MyThread1
MyThread4
MyThread3
MyThread5
MyThread1
MyThread4
MyThread3
MyThread5
MyThread1
MyThread4
MyThread5
MyThread1
MyThread3
MyThread5
MyThread1
MyThread3
MyThread5
MyThread1
MyThread3
MyThread5
MyThread1
MyThread4
MyThread5
MyThread4
MyThread5
MyThread4
MyThread4
MyThread4
MyThread4
MyThread4
MyThread1
MyThread1

-------------------------------------
[quote]就是线程的原因了,线程被执行的时机是不定的。
5个线程未同步的结果:
===========================
MyThread2
MyThread2
MyThread2
MyThread2
MyThread2
MyThread2[/quote]
我说的是同步后  执行的顺序是先2后1

-------------------------------------
[quote]我说的是同步后  执行的顺序是先2后1[/quote]
一样的原因啊,线程2被先执行了。虽然你后调用的它。

-------------------------------------
关键是每次都这样啊

-------------------------------------
[quote]关键是每次都这样啊


估计线程2是VIP客户吧,哈哈
 

评论 COMMENTS
没有评论 No Comments.

添加评论 Add new comment.
昵称 Name:
评论内容 Comment:
验证码(不区分大小写)
Validation Code:
(not case sensitive)
看不清?点这里换一张!(Change it here!)
 
评论由管理员查看后才能显示。the comment will be showed after it is checked by admin.
CopyRight © 心缘地方 2005-2999. All Rights Reserved