我试图理解一部分代码,其中涉及在对象上进行同步,并且其中一个同步块更改了该对象的某些字段。我正在查看的代码类似于以下内容:
public class ClassA {
private ClassB someObject = new ClassB();
public void FuncA() {
synchronized(someObject) {
//change some field of someObject
}
}
public void FuncB() {
synchronized(someObject) {
//change some field of someObject
}
}
}
这是安全的做法吗?我已经在线阅读了几页描述锁的安全操作的页面,但似乎没有一个能处理类似的例子。
感谢您的帮助。谢谢!
答案 0 :(得分:1)
是的,很好。
例如,这基本上是您从多个线程写入ArrayList
时可以执行的操作:您在列表上进行了同步,并更新了其字段(内部数组,大小等)。
注意事项是,您也不得在任何地方以非同步方式访问someObject
。
public class ClassA {
private ClassB someObject = new ClassB();
public void FuncA() {
synchronized(someObject) {
//change some field of someObject
}
}
// ...
// BAD! Don't do this.
public void FuncC() {
// read some field of someObject
}
}
答案 1 :(得分:1)
您可以通过多种方式来同步对方法的访问。
根据同步要求,一个看起来比另一个更好。
这是安全的做法吗?
如果将它用于适合的用例,这是一种安全的做法。
在这里,同步很有意义,因为它锁定了someObject
,这两个方法对它们进行了修改。
是的,您可以在this
上进行同步,也可以同步整个方法,例如:
public class ClassA {
private ClassB someObject = new ClassB();
public void FuncA() {
synchronized(this) {
//change some field of someObject
}
}
public void FuncB() {
synchronized(this) {
//change some field of someObject
}
}
}
,但是这些将锁定整个对象,而这可能不是必需的。
答案 2 :(得分:1)
是的,这很安全。 someObject
是私有的,因此只有FuncA
和FuncB
可以访问它。它们都在someObject
上同步,因此即使来自不同的运行线程,一次也只能在someObject
上执行一种方法。
请注意,重要的是,ClassA
的所有要访问someObject
的方法都应在synchronized
的{{1}}内这样做,以免出现读写不一致的风险声明为someObject
(除非您确切地了解自己在做什么!)。