Continuable.java Java
程序员文章站
2024-02-21 11:59:34
...
有这么一个函数:
我需要有一系列的key需要操作,那么就必须弄一个循环:
如果storage是一个网络上的设备,key又非常多。这就会造成非常多次的网络操作。假设有500个key,每次网络操作是100ms。那么就需要耗费500 * 0.1 * 2 = 100秒的时间。
那么怎么解决这个问题呢?最直观的想法就是批量:
但是这样做的问题是所有使用increase的地方也必须是批量处理的了。底层的一个优化扩散到了最上层,使得整体的逻辑变复杂了。
最后的解决办法是:
而Continuable.java实现的就是$return和$yield,把一个完整的函数打散成step来执行。
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来执行。