4

假设我有以下情况:

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

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

phoneList.remove(index);

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

4

6 回答 6

3

是的。为什么不?

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

于 2013-09-04T10:27:56.650 回答
3

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

于 2013-09-04T10:28:06.760 回答
2

是的。

由于您正在Phone实例上同步,因此这是可能的。另一个线程可以phoneArrayList. 但是您的phone参考将指向同一个实例。

为确保没有其他线程可以从其他地方访问您的列表,请在列表本身上同步 -

synchronized(phoneList)
{
    //some code runs here
}
于 2013-09-04T10:27:43.800 回答
2

当然。锁定Phone不会锁定列表。

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

backingArray[i] = null;
于 2013-09-04T10:27:58.380 回答
2

在这里,它只是为synchronization里面的一组语句提供了for synchronized,从不关心phone获取到的实例。从 中移除phone对象phoneList是可能的。但请记住, Java不会从内存中删除一个对象,直到它还剩下一些引用。

于 2013-09-04T10:53:14.740 回答
1

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

由于只有电话对象是同步的,您可以从列表中删除元素。因此,当您尝试从列表中删除元素时,您不会得到UnsupportedOperationException 。

但是如果引用丢失或为空。当您尝试对电话对象进行操作时,您可能会收到NullPointerException 。

于 2013-09-04T10:35:19.523 回答