在下面的代码中,在HashSet的每个元素上调用一个本地方法。如果它返回一个特殊值,我们就会停止循环。否则,我们将每个返回值添加到新的HashSet。
HashSet<Object> myHashSet=…;
HashSet<Object> mySecondHashSet=…;
for (Object s : myHashSet) {
Object value = my_method(s);
if(value==specialValue)
return value;
else
mySecondHashSet.add(value);
}
我想把这个过程分开。 HashSet中的任何对象都没有任何共同的对象(它是树状结构),所以我知道它们可以在没有任何同步问题的情况下运行。如何修改代码,使my_method的每个调用开始一个新的步骤,并且如果其中一个线程评估为特殊值,所有线程停止而不返回并返回特殊值?
答案 0 :(得分:1)
考虑到java 8,这可能相对简单,但它不会保留您的初始代码语义:
如果您需要的只是在点击后返回特殊值
from concurrent.futures import TimeoutError
from pebble import ProcessPool
def function(n):
return n
with ProcessPool() as pool:
future = pool.schedule(function, args=[1], timeout=10)
try:
results = future.result()
except TimeoutError as error:
print("function took longer than %d seconds" % error.args[1])
如果你需要保持变换值直到你达到特殊值,你已经在评论中得到了@Elliot的答案,同时需要提到语义与你的原始代码不同,因为没有orderer会被保留。
虽然尚未检查,但我希望以下优化并停止一旦它达到想要的特殊价值:
$cart[$product->id] = $quantity;
var_dump($cart);
return redirect('catalogs')->withCookie(cookie()->forever('cart', serialize($cart)));
答案 1 :(得分:0)
我会两次通过:
为每次转换启动一个新线程太重了,会让你的机器瘫痪(除非你的元素很少,在这种情况下,并行化可能不值得付出努力。
为避免使用my_method
两次转换值,您可以懒惰地进行转换并记住结果:
private class Memoized {
private Object value;
private Object transformed;
private Function<Object, Object> transform;
public Memoized(Object value, Function<Object, Object> transform) {
this.value = value;
}
public Object getTransformed() {
if (transformed == null) {
transformed = transform.apply(value);
}
return transformed;
}
}
然后您可以使用以下代码:
Set<Memoized> memoizeds =
myHashSet.stream() // no need to go parallel here
.map(o -> new Memoized(o, this::my_method))
.collect(Collectors.toSet());
Optional<Memoized> matching = memoized.parallelStream()
.filter(m -> m.getTransformed().equals(specialValue))
.findAny();
if (matching.isPresent()) {
return matching.get().getTransformed();
}
Set<Object> allTransformed =
memoized.parallelStream()
.map(m -> m.getTransformed())
.collect(Collectors.toSet());