`
taowen
  • 浏览: 193559 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Continuable.java

阅读更多
有这么一个函数:
public void increase(String key) {
  int val = storage.get(key);
  storage.put(key, val + 1);
}

我需要有一系列的key需要操作,那么就必须弄一个循环:
for (String key : keys) {
  increase(key);
}

如果storage是一个网络上的设备,key又非常多。这就会造成非常多次的网络操作。假设有500个key,每次网络操作是100ms。那么就需要耗费500 * 0.1 * 2 = 100秒的时间。
那么怎么解决这个问题呢?最直观的想法就是批量:
public void increase(Collection<String> keys) {
  Map<String, Integer> vals = storage.get(keys);
  for (Map.Entry<String, Integer> entry : vals) {
    entry.setValue(entry.getValue() + 1);
  }
  storage.put(vals);
}

但是这样做的问题是所有使用increase的地方也必须是批量处理的了。底层的一个优化扩散到了最上层,使得整体的逻辑变复杂了。
最后的解决办法是:
public interface Storage {
  Continuable<Integer> get(String key);
  Continuable<Void> put(String key, String value);
}
public Continuable<Void> increase(final String key) {
  return new Continuable<Void>(){
    private Future<String> val;
    protected void step1() {
      val = $yield(storage.get(key));
    }
    protected void step2() {
      $yield(storage.put(val.get() + 1));
    }
    protected void step3() {
      $return();
    }
  };
}

而Continuable.java实现的就是$return和$yield,把一个完整的函数打散成step来执行。
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics