rusong110 2008-12-16 18:06
浏览 229
已采纳

用java容器实现缓存

有这么个问题:
应用程序定时的读取数据库,并将数据写入缓存.
为避免用户读缓存时,程序更新缓存,使用户读到错误数据,使用了java的同步容器Hashtable和Vector实现.
根据数据库字段值的不同,将数据分别放到几个不同的Vector.
类似这样
[code="java"]Vector v1 = new Vector();
..
for(数据){
if (数据i.属性 == "name")
v1.add(数据i)
}
..
static h.add("name",v1);[/code]
..
像这样的代码没什么扩展性,而且很依赖数据库数据.但是它有个好处,就是线程安全.用户读到的数据都是有效的.

如果根据数据库数据动态生成Vector,像这样
[code="java"]for(数据){
Vector v = null;
if(hash.containsKey(属性)){
v = hash.get(属性)
v.add(数据i)
}else{
v = new Vector();
v.add(数据i);
hash.add(v);
}
}[/code]
也有问题,就是Vector里新写入的对象会和原来的重复.

如果先清理缓存hash.clear();则可能此时用户正在读数据,结果读不到任何数据.或者任何时候在Vector写入新数据都要删除原数据,正样都有可能使用户读不到数据..

有什么办法,即可以让用户读到有效数据,又能保留程序灵活性
[b]问题补充:[/b]
不知道我的描述是否清楚,

业务需求是在更新数据的时候进行同步控制,
用new Vector这种方式,相当于vector.add(数据)的时候,用户依然可以读之前存在hashtable中的数据,只是最后在hash.add(Vector)的时候才进行同步,这个时间是很短的,因为只有几个Vector(Vector里面的数据会很多)被加入到hashtable.

如果不考虑容器,而是手动在更新缓存的前后加锁,解锁,那么这个时间会比较长,可能达不到上一种实现的性能.

用Concurrent包,能达到甚至超过上一种实现的性能吗.
[b]问题补充:[/b]
concurrent是不错,可惜解决不了我的问题.
测试了一下,
hashtable.add("",vector)只有几个vector,在毫秒级别上耗时为0.
用concurrent把更新缓存的过程锁定,其间循环一万条数据并添加到ArrayList,然后添加到hashmap,耗时约16毫秒,还是很有差距...
[b]问题补充:[/b]
你们的答案都类似,分数只能给一个人。

Concurrent不太了解,我的问题是要求锁定的时间尽可能短,即便concurrent有同步的list,我还是要清空list,然后把新数据写入,list要装的数据量是很大的,这样可能会让用户等待时间比较长.

我现在的做法,是把数据写入新的list,这过程不需要同步,最后把list写入hashtable,这个过程需同步,可list数量很少,所以这个过程时间很短。代价就是牺牲了一些可维护性和扩展性。

  • 写回答

4条回答

  • 不良校长 2008-12-16 23:41
    关注

    这个问题很简单, 首先, 你操作数据库的时候, 

    Vector/Hashtable 你不要用了, 用Concurrent包

    如果说, 你需要整个替换数据, 那么我建议你, 把数据库读入的时候, 放在一个新的Vector/Hashtable.然后, lock 老的 Vector/Hashtable 对象, 把新的对象 [b]assgin[/b]过去. 这样, 你就不需要使用同步了。

    不过, 我建议你使用Concurrent包。 直接把新数据写进去.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(3条)

报告相同问题?

悬赏问题

  • ¥30 这是哪个作者做的宝宝起名网站
  • ¥60 版本过低apk如何修改可以兼容新的安卓系统
  • ¥25 由IPR导致的DRIVER_POWER_STATE_FAILURE蓝屏
  • ¥50 有数据,怎么建立模型求影响全要素生产率的因素
  • ¥50 有数据,怎么用matlab求全要素生产率
  • ¥15 TI的insta-spin例程
  • ¥15 完成下列问题完成下列问题
  • ¥15 C#算法问题, 不知道怎么处理这个数据的转换
  • ¥15 YoloV5 第三方库的版本对照问题
  • ¥15 请完成下列相关问题!