【问题标题】:Grails Page CounterGrails 页面计数器
【发布时间】:2014-02-17 08:47:00
【问题描述】:

我需要为某些页面创建一个计数器。 所以我创建了一个名为 Counter 的域:

class Counter {
  java.sql.Date date;
  Member member;
  int count;
  int submit;

  //setter and getter...
}

Count 是这个页面打开了多少次,submit 是提交了多少次表单(联系表单的种类)。

我创建了一个名为 CounterService 的服务:

class CounterService {
  List counters;

  def load() {
    counters = Counter.findAllByDate(new java.sql.Date(System.currentTimeMillis()));
  }

  def increaseCount(Member member) {
    counters.each { 
      if(it.member.id = member.id) it.setCount(it.count + 1);
    }
  }

  //the rest of the code...
}

我将使用 Quartz 作业每小时将计数器保存到数据库中。

你认为这个计数器变量是多线程安全的吗?因为 CounterService 会在很多 Controller 中被调用。 我需要在服务器启动之前调用 load 并且我不知道在哪里调用它。 对我应该在哪里调用 load() 有什么建议吗? 或者,也许是页面计数器的更好解决方案?

【问题讨论】:

    标签: grails hitcounter grails-services


    【解决方案1】:

    您为什么使用java.sql.Date?普通的java.util.Date 可以用更少的代码开销做同样的事情。

    我不会为此使用普通的Map。我宁愿使用休眠缓存:

    Counter counter = Counter.findByDate( someDate, [ cache:true ] );
    

    以便对象在缓存中保存 5 或 10 分钟(根据默认的 ehcache-settings,不记得确切的值)

    另一个选择是,如果您真的需要一次所有计数器,则使用 ConcurrentHashMap 进行缓存,这确实强制线程安全:

    class CounterService {
      ConcurrentHashMap counters
      ....
    }
    

    【讨论】:

    • java.util.Date 包含时间,而 java.sql.Date 没有。谢谢,我会根据你的建议使用 ConcurrentHashMap 。但是,我应该在哪里调用 load()?
    • 抱歉,这应该是列表而不是地图。我已将问题编辑为列表。
    • java.util.concurrent.ConcurrentSkipListSet 为例
    猜你喜欢
    • 2011-08-22
    • 1970-01-01
    • 2015-07-05
    • 2014-08-12
    • 2012-04-17
    • 2011-07-28
    • 2015-12-25
    • 2013-07-02
    • 2012-03-04
    相关资源
    最近更新 更多