论坛首页 Java企业应用论坛

static的常驻内存

浏览 11985 次
精华帖 (3) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (3)
作者 正文
   发表时间:2008-11-24  
其实都没问题。LZ选择案例要慎重阿。。。。
0 请登录后投票
   发表时间:2008-11-25  
怎么这么多人批判~~   只是说的一个方式而已,  需要全局有很多方法 比如web中放app等.  随便说说而已
0 请登录后投票
   发表时间:2008-11-25  
<code>
public static Object getExpMap(String key){ 
    synchronized(this){ 
        return expMap.get(key); 
      } 
}
</code>
这个能编译过去吗?
0 请登录后投票
   发表时间:2008-11-26  

没有必要用synchronized吧,

现在不都是java.util.concurrent时代了吗?
0 请登录后投票
   发表时间:2008-11-26  
timerri 写道
为什么不要修改了再clone,因为这样就使内存中存在了2个功能完全相同的副本。而其中一个无用。这样的使用方式只在很少的情景下才需要出现。我很奇怪的是为什么要对外返回一个内部对象的副本而不是提供一个查询内部对象的方法?


返回对象的副本是保证线程安全的一种方式,也就是CopyOnWrite,它主要用于写(或更新)操作比较少的情况下,主要的好处是客户端不需要同步访问,主要缺点是下一次更新时客户端得不到最新的数据。直接返回对象当然可以,它和CopyOnWrite的优缺点刚好相反,缺点是客户端访问时需要同步,优点是客户端可以得到最新的数据。
0 请登录后投票
   发表时间:2008-11-30  
提个建议,这个类你是否要考虑到单例,个人觉得要保护好你的STATIC 还有同步呢?
再则,怎么方法都没有抛出异常,如果指定KEY找不到VALUE是不是返回NULL呢?如果这样外部是否还要判断,你这块的逻辑需要补充。
哦 对了 最好在方法里面加final 避免恶意修改,反正你也不要继承的。
个人意见,仅供参考。
0 请登录后投票
   发表时间:2008-11-30  
timerri 的克隆做法我觉得不应该做在这一层。因为这层提供了修改和获取两个函数,你就是克隆了也不能起到什么作用,如果在上一层只提供一个返回MAP的接口 这时候不允许外部程序修改MAP 倒是可以考虑使用克隆。

再则,修改全局变量的时候你应该让修改的线程拥有令牌,只允许它操作,这个过程是一个短暂的过程,如果这个时候你拿给别人一个脏数据它也是没有用的。这种情况是无法避免的,要么你就让要获取的线程等待,要么就直接给它异常,让他下次再试。

个人意见,仅供参考
0 请登录后投票
   发表时间:2008-11-30  
gavin.zheng 写道


class Config{

private static HashMap expMap = new HashMap();

public static Object getExpMap(String key){
   synchronized(this){
       return expMap.get(key);
     }
}

}


 

这里你猜猜会发生什么事情~static method里synchronized(this)..........

 

niveko 写道
你为什么不使用private static Map expMap = new ConcurrentHashMap();
这样不是减少你同步的问题,性能也好些吗?

 

niveko说得对,java.util.concurrent就可以了。

 

0 请登录后投票
   发表时间:2008-11-30  
gavin.zheng 写道
对于配置等经常使用的对象,而且基本上在使用的时候很少修改的,我们可以让它常驻内存.

如何常驻内存,这是我们最关心的.这就是static的使用技巧,
照例以配置文件来讨论,请看以下代码

class Config{

private static HashMap expMap = new HashMap();

//装载personMap,为简单不使用singleton模式
public Config(){
   //读取配置文件,并装载进expMap
   loadExpMap();
}

public static Object getExpMap(String key){
   synchronized(this){
       return expMap.get(key);
     }
}

public static HashMap setExpMap(String key, Object o){
   synchronized(this){
       expMap.put(key, o);
     }
   return expMap.clone();
}

public static Object removeExpMap(String key){
   synchronized(this){
       expMap.remove(key);
     }
   return expMap.clone();
}

}



注意以下2点
所有的调用方法如果不是确定已经被同步,误必使用synchronized,当然,你说用rw锁也行^^
如果需要返回,为其他线成或者其他此对象消费者着想, 请clone,



顺带说下,关于JNDL之类的动态装载工厂方法是如何实现的.
JNDI的动态装载方式在ResourcesManager类中,使用的是类似我这样的static常驻内存方式,不过他使用的是WeakHashMap做的引用, 也就是说当不使用这些工厂对象时候,里面的引用对象会被自动回收

不要轻易用它!!太高级了,贵啊,一般情况我们用不起^^, 它会对每个加入其中的对象产生线成去检测回收的


回各位大大的话
1为什么需要同步,涉及到多线城同步是必须的,只是看你的使用方式问题而已, 比如有位仁兄说性能消耗太高,这不是问题的问题.  如果不是static, 比如说cache 然后类似使用servlet装载进app做全局的话, 也有点这个的意思, 当然,这个时候由于可能读写巨大,所以就只能尽量使用rw锁了,性能上优化点.
2为什么clone,既然是一个公共对象,你把引用的值返回出去你放心??可能会被外面的资源通过这个引用修改它的,所以不要直接返回.
3这是个简单的全局对象的例子,到底里面是什么无所谓,所以不存在什么set get的问题




楼主这样的代码,实在是太误导新手了吧~~~~
怎么看,也看不出synchronized和clone是干啥用的?请问LZ,下面的情况,是不是可能有问题啊?

1、关于synchronized
第一个线程搞到第20行执行完,挂起;
第二个线程搞18~20行,然后也挂起;
第一个线程醒过来,继续搞21行,此时,第二个线程中的“o”对象已经弄进expMap中了呀,由此,这里的同步想不明白是干么的啊?
2、关于HashMap的clone
HashMap的clone是浅表副本:并不复制键和值本身。
所以,你光把HashMap给clone了,里面的东东没有clone,不是一样可以修改里面的东西吗?所谓的引用修改,不是照样没避免吗?

综上,感觉本文没有价值啊?

1 请登录后投票
   发表时间:2008-12-18  
gavin.zheng 写道

public static HashMap setExpMap(String key, Object o){
   synchronized(this){
       expMap.put(key, o);
     }
   return expMap.clone();
}

public static Object removeExpMap(String key){
   synchronized(this){
       expMap.remove(key);
     }
   return expMap.clone();
}

}



支持timerri 的看法, 这里set方法确实用synchronized 不太好
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics