Java和同步两个线程
我有两个线程修改相同的对象。对象是Java和同步两个线程,java,synchronization,Java,Synchronization,我有两个线程修改相同的对象。对象是ArrayList中的自定义非同步对象(不是向量)。我想让这两个线程很好地协同工作,因为它们是同时被调用的 这里是线程1中唯一重要的方法 public void doThread1Action() { //something... for(myObject x : MyArrayList){ modify(x); } } 以下是线程2中的一个方法: public void doThread2Action() { //somethi
ArrayList
中的自定义非同步对象(不是向量)。我想让这两个线程很好地协同工作,因为它们是同时被调用的
这里是线程1中唯一重要的方法
public void doThread1Action() {
//something...
for(myObject x : MyArrayList){
modify(x);
}
}
以下是线程2中的一个方法:
public void doThread2Action() {
//something...
for(myObject x : MyArrayList){
modifyAgain(x);
}
}
目前,在测试时,我偶尔会收到“ConcurrentModificationExceptions”。(我认为这取决于线程1在线程2尝试修改对象之前完成迭代的速度。)
我是否正确地认为,通过简单地在这两个方法的开头添加
synchronized
,线程将以同步的方式协同工作,而不是尝试访问ArrayList
?或者我应该将数组列表
更改为向量
?ConcurrentModificationException不是源于修改集合中的对象,而是源于在迭代器处于活动状态时添加/删除集合
共享资源是集合,必须有第三个使用和添加/删除的方法。要获得正确的并发性,必须在访问集合资源的所有方法中同步对集合资源的访问
为了避免过长的同步块,常见的模式可能是将集合复制到同步块中,然后对其进行迭代。如果您这样做,请注意,您首先谈论的问题(并发修改对象)是再次到位——但这一次您可以锁定另一个资源。您不需要同步对列表的访问,只要您不在结构上修改它,即,只要不在列表中添加或删除对象。您也不应该看到
ConcurrentModificationException
s,因为只有在结构上修改列表时才会抛出这些异常
因此,假设您只修改列表中包含的对象,而不在列表中添加、删除或重新排序对象,则可以在修改所包含的对象时对其进行同步,如下所示:
void modifyAgain(MyObject x) {
synchronized(x) {
// do the modification
}
}
我不会在modifyreach()
方法上使用synchronized
修饰符,因为这不允许同时修改列表中的两个不同对象
当然,另一个线程中的
modify()
方法的实现方式必须与modifyreach()
相同,您需要在同一个锁上同步对集合的访问,因此仅在方法上使用synchronized关键字(假设它们在不同的类中)将锁定两个不同的对象
下面是您可能需要做的一个示例:
Object lock = new Object();
public void doThread1Action(){
//something...
synchronized(lock){
for(myObject x : MyArrayList){
modify(x);
}
}
public void doThread2Action(){
//something...
synchronized(lock){
for(myObject x : MyArrayList){
modifyAgain(x);
}
}
也可以考虑使用<代码> CopyOnWorksRayList而不是<代码> vector < /COD>
< P>我猜您的问题与*此异常可能由检测到的方法引发 并发
*在不允许修改对象时对该对象进行修改 允许的 */ 在您的例子中,问题是列表中的迭代器,可能会被修改。我想通过以下实施,您的问题将得到解决:
public void doThread1Action()
{
synchronized(x //for sample)
{
//something...
for(myObject x : MyArrayList)
{
modify(x);
}
}
}
然后:
public void doThread2Action()
{
synchronized(x //for sample)
{
//something...
for(myObject x : MyArrayList)
{
modifyAgain(x);
}
}
}
为了取得更好的结果,我希望任何人都能纠正我的解决方案