Ion*_*anu 4 java methods locking synchronize
我有一个很大的问题要问你.如何从同一个类同步两个不同的方法以锁定同一个对象?这是一个例子:
public class MyClass extends Thread implements Observer{
public List<AnotherClass> myList = null;
public MyClass(List<AnotherClass> myList){
this.myList = myList;
}
public void run(){
while(true){
//Do some stuff
myList.add(NotImportantElement);
}
}
public void doJob{
for(int i=0; i<myList.size; i++){
ElementClass x = myList.get(i);
//Do some more stuff
}
}
}
Run Code Online (Sandbox Code Playgroud)
问题是如何在执行doJob时停止run()访问myList,反之亦然?
想象一下:我启动线程并开始向列表中添加元素.在一个随机的时刻,我从另一个持有对我的线程的引用的类调用doJob().
我应该怎么做锁?谢谢!
LE
好吧,我理解锁的概念,但现在我有另一个问题.
假设我有一个类,public static myList并且只有该类的一个实例.从那个实例开始,我创建了一个n实例Thread来获取该列表的每个元素并用它做一些事情.
现在,在特定时刻,myList更新.那些已经在处理myList元素的线程会发生什么?myList在更新时如何锁定访问权限?
注意:此代码假定您只有一个MyClass实例.根据你的帖子,听起来像是这样的.
public class MyClass extends Thread implements Observer{
private List<AnotherClass> myList = null;
private Object lock = new Object();
public MyClass(List<AnotherClass> myList){
this.myList = new ArrayList(myList);
}
public void run(){
while(true){
//Do some stuff
synchronized(lock) {
myList.add(NotImportantElement);
}
}
}
public void doJob{
synchronized(lock) {
for(int i=0; i<myList.size; i++){
ElementClass x = myList.get(i);
//Do some more stuff
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
编辑:添加了制作List的副本,以便外部实体无法根据JB Nizet更改列表
编辑2:将变量设为私有,以便其他人无法访问它们
你可以:
run和doJob synchronized。这将this用作锁;final并在其上同步。这将使用列表作为锁。将锁定字段声明为final一种很好的做法。这样,您的类的某些方法可以在一个对象上同步,而其他方法可以使用其他对象进行同步。这减少了锁争用,但增加了代码复杂性;java.util.concurrent.locks.Lock变量并使用它的方法进行同步。这将提高代码的灵活性,但也会增加代码的复杂性;BlockingQueue或CopyOnWriteArrayList。这将降低代码复杂度并确保线程安全。volatile字段来使用同步。请参阅此SO 帖子。这将确保安全,但会大大增加复杂性。第二个想法,不要这样做:)