Java线程安全重的对象,需要建议

时间:2015-07-09 10:37:11

标签: java multithreading

我的客户端基本上每5秒从我的应用程序相同数据请求。目前,我正在为每个用户查询数据库,但这似乎不是一个有效的解决方案。

我正在考虑在this answer中创建一个包含该对象的线程安全单例,该对象每隔几分钟就会刷新一次。

这是正确的道路,还是您有其他建议吗?

对我而言,这似乎是一个常见的问题,我认为可能存在开箱即用的解决方案。

3 个答案:

答案 0 :(得分:2)

您在此处引用的设计模式是cache

如果数据是相对静态的,您可以以某种方式缓存数据库响应,可能是Map,其中某些键是根据请求的参数构建的,并且可能基于时间有一些过期(例如1小时或1天)。

Singleton确实是可共享对象的实现,例如您需要的缓存。请注意,您引用的其他答案涉及线程安全性。这在(例如)可以按会话或按请求使用线程的Web服务环境中尤为重要。

请注意,Singletons被许多人视为糟糕的编程习惯,尤其是因为它们难以测试。

因此,实现缓存的另一种方法是通过单例线程安全缓存bean和" wire"它通过依赖注入需要使用它的所有地方。

PS。 Guava库有一个缓存构建器,可以使用基于时间的过期策略进行配置。

PPS。如果要跨多个服务器进行缓存,可以考虑使用hazelcast等网格解决方案。

答案 1 :(得分:1)

如果您的数据经常被阅读但不经常更改(或者甚至是静态的),那么cqengine就是您的朋友

答案 2 :(得分:1)

如果你不介意你的一些“用户”拿到了进入数据库的命中,你就可以使用简单的缓存,如下所示:

    import java.util.concurrent.atomic.AtomicLong;

    public class DbData {

         AtomicLong lastVisistToDB = new AtomicLong();
        volatile Object dataFromDb;
        long freshnessInterval = 1000 * 60; // 1 minute

        public DbData() {
            getFromDb();
        }    

        Object getData() {
            if(System.currentTimeMillis() - lastVisistToDB.get() > freshnessInterval) {
                getFromDB();
            }
            return dataFromDb;
        }

        private void getFromDb() {
            dataFromDb = getDataFromDb(...);
            lastVisistToDB.set(System.currentTimeMillis());
        }
    }

请注意,如果多个“用户”要求数据不新鲜 - 您将多次调用数据库。然而,一旦发生这种情况,你可以持续1分钟或其他任何事情 您在freshnessInterval

中设置的持续时间