我在java中使用synchronized关键字时遇到了一些问题。我确实理解线程在方法或代码块上获得锁的部分,但我不知道如何在下面的示例中使用它。
我有两个不同的线程(线程A和线程B)和一个Class1,它包含一个包含Class2实例的列表开关。threadA调用的Class1.methodA()修改列表中的信息。线程B调用的Class1.methodB()只使用列表中的信息。
我得出的结论是,当线程A在修改列表中的数据,而线程B正在使用它时,我的程序中会出现问题
我是否应该在Class1中创建一个同步的方法,然后调用MethodA或MethodB(对我来说似乎是多余的)。或者线程可以仅在正在修改的Class2的特定实例上获得锁吗?
我很抱歉英语不好。
在列表上同步两个方法:
methodA()
{
synchronized(list)
{
... use the list, no one else can touch it
}
... do other stuff.
}
方法B()相同
点击此处了解更多信息。
这里有关于线程的解释
好吧,回到你的问题上来。实际上,您可以只使用列表中的synchronize,并在该synchronize块中进行读取或添加。
synchronized(yourList)
{
// do something
}
否则,我想您可以使用java.util.concurrent
包中的CopyOnWriteArrayList
(API)。但这确实很昂贵,因为它总是生成底层数组的新副本。
CopyOnWriteArrayList<String> myArrayList = new CopyOnWriteArrayList<String>();
myArrayList .add("Stackoverflow");
Iterator<String> iterator = myArrayList .iterator();
while (iterator.hasNext())
System.out.println(iterator.next());
}
另一种方法是使用synchronizedList
List list = Collections.synchronizedList(new ArrayList());
synchronized(list) {
Iterator i = list.iterator();
while (i.hasNext())
foo(i.next());
}
但最终您仍然需要同步块。add和remove方法本身是原子和线程安全的,但对列表进行迭代则不是。