假设我有以下情况:
final int index = 10;
Phone phone = phoneList.get(index);
synchronized(phone)
{
//some code runs here
}
因此,当电话对象(通过 phoneList.get() 方法获得)被锁定时,另一个线程可以执行该方法:
phoneList.remove(index);
并将给定索引处的电话对象设为空?
假设我有以下情况:
final int index = 10;
Phone phone = phoneList.get(index);
synchronized(phone)
{
//some code runs here
}
因此,当电话对象(通过 phoneList.get() 方法获得)被锁定时,另一个线程可以执行该方法:
phoneList.remove(index);
并将给定索引处的电话对象设为空?
是的。为什么不?
但是,仍然phone
会指向同一个对象。即对象从列表中删除,但 jvm 仍然引用它。
一个操作与另一个无关:synchronized
不保护对任何特定对象的访问。如果您的remove
操作在synchronized
使用与锁相同的对象的块内,那么它将不得不等待;如果不是,它将成功删除该对象,而不会影响将synchronized
其用作锁的块。从列表中删除对象不会将该对象变成垃圾,直到它的监视器被任何线程锁定。
是的。
由于您正在Phone
实例上同步,因此这是可能的。另一个线程可以phone
从ArrayList
. 但是您的phone
参考将指向同一个实例。
为确保没有其他线程可以从其他地方访问您的列表,请在列表本身上同步 -
synchronized(phoneList)
{
//some code runs here
}
当然。锁定Phone
不会锁定列表。
此外,要从列表中删除元素,您不需要使用该元素。删除很简单:
backingArray[i] = null;
在这里,它只是为synchronization
里面的一组语句提供了for synchronized
,从不关心phone
获取到的实例。从 中移除phone
对象phoneList
是可能的。但请记住, Java不会从内存中删除一个对象,直到它还剩下一些引用。
当您执行 phoneList.get(index) 时,它会为您提供从列表到 Phone 对象的对象引用。
由于只有电话对象是同步的,您可以从列表中删除元素。因此,当您尝试从列表中删除元素时,您不会得到UnsupportedOperationException 。
但是如果引用丢失或为空。当您尝试对电话对象进行操作时,您可能会收到NullPointerException 。