我有一套独特的元素.每个元素都有一组可以执行的操作,但每个元素操作都独立于其他元素操作.例如,有三个操作:每个元素可以执行的O1,O2,O3.现在每个元素都可以执行O1,O2,O3而不会与其他元素冲突.但是,执行操作时的每个元素必须专门执行O1,O2,O3(一次一个).
在这种情况下,它是一种锁定元素的好方法.它会起作用吗?还有其他方法,例如ReentrantLock或java8以更好的方式执行此操作吗?
例如
for(Element element : elements) {
synchronized(element) {
//Perform O1,O2,O3 but one at a time
}
}
假设可以从多个位置调用上面的for循环,并且将for循环写入代码中的多个位置以执行元素的不同操作.
解决方法:
正如markspace建议的那样,最安全的选择可能是让你的操作同步,而不是依赖所有的调用者来正确地做到这一点,例如:
public class Element {
public synchronized void O1() { ... }
public synchronized void O2() { ... }
public synchronized void O3() { ... }
}
这将确保对于给定的Element实例,一次只调用一个操作.然后,您的呼叫者无需担心显式同步任何内容:
for(Element element : elements) {
element.O1();
element.O2();
element.O3();
}
但是,如果您需要确保这些单独的操作(O1,O2和O3)全部一起发生,而不与其他可能的呼叫者交错,那么这将是不够的.在这种情况下,最安全的选择是在Element上引入新方法来执行您需要的操作,而不是尝试在外部编写它们:
public class Element {
// ...
public synchronized void doAllOperations() { O1(); O2(); O3(); }
}
这确保了doAllOperations()中的所有内容都将在此瞬间相对于任何其他调用以原子方式发生.