迭代ArrayList时同步对象

时间:2013-09-04 10:24:29

标签: java synchronization thread-safety

假设我有以下情况:

final int index = 10;
Phone phone = phoneList.get(index);
synchronized(phone)
{
   //some code runs here
}

因此,当phone对象(通过phoneList.get()方法获得)被锁定时,另一个线程可以执行该方法:

phoneList.remove(index);

并将给定索引处的电话对象置空?

6 个答案:

答案 0 :(得分:3)

是。为什么不呢?

但是,phone仍将指向同一个对象。即对象从列表中删除但jvm仍然引用它。

答案 1 :(得分:3)

一个操作与另一个操作无关:synchronized不保护对任何特定对象的访问。如果您的remove操作位于synchronized块内,该块使用与锁相同的对象,则必须等待;如果不是,它将成功删除该对象,而不会影响将其用作锁的synchronized块。从列表中删除对象不会将对象变为垃圾,直到其监视器被任何线程锁定。

答案 2 :(得分:2)

由于您正在Phone实例上进行同步,因此这是可能的。另一个线程可以从phone中删除相同的ArrayList对象。但是您的phone引用将指向同一个实例。

要确保没有其他线程可以从其他位置访问您的列表,请在列表本身上进行同步 -

synchronized(phoneList)
{
    //some code runs here
}

答案 3 :(得分:2)

Ofcourse。锁定Phone 锁定列表。

此外,要从列表中删除元素,您不需要使用该元素。删除非常简单:

backingArray[i] = null;

答案 4 :(得分:2)

这里,它只为synchronization中的一组语句提供synchronized,而不关心获得的phone实例。可以从phone中删除phoneList对象。但请记住, Java 不会从内存中删除对象,除非它有一些引用。

答案 5 :(得分:1)

当你执行phoneList.get(index)时,它会为你提供从列表到Phone对象的对象的引用。

由于只有手机对象同步,您可以从列表中删除元素。因此,当您尝试从列表中删除元素时, NOT 会获得UnsupportedOperationException

但是如果引用丢失或为null。当您尝试操作手机对象时,您可能会获得NullPointerException