this.synchronized是否保护您免受垃圾收集器的侵害?

时间:2014-04-17 15:49:09

标签: scala garbage-collection

我有一些使用WeakReference的代码。我不得不实现一个丑陋的解决方法来解决问题,但我想知道只是添加一个this.synchronized可能会解决我的垃圾收集器问题。这是代码,问题出在函数create

  /**
   * The canonical map.
   */
  var unicityTable = new WeakHashMap[CanonicalType, LightWeightWrapper[CanonicalType]] with SynchronizedMap[CanonicalType, LightWeightWrapper[CanonicalType]]

  /**
   * Create a new element from any object.
   * @param from the object that will be used to generate a new instance of your canonical object.
   */
  def create(from: FromType) = {
    val newElt = makeFrom(from)
      // I wonder if adding a this.synchronized here (and of course removing the test for garbage collection) might solve the problem more elegantly 
      val wrapper = unicityTable.get(newElt)
      wrapper match {
        case Some(w) => w._wrap.get match { // if the element is in the map
          case Some(element) => element // the element was not garbage collected while we obtaining it
          case None => // some how, the wrapped element was garbage collected before we get it, so we recreate it, and put it back
            unicityTable.put(newElt, LightWeightWrapper(newElt))
            newElt
        }
        case None => // the element is not in the map
          unicityTable.put(newElt, LightWeightWrapper(newElt))
          newElt
      }

  }

  class LightWeightWrapper[T <: AnyRef] private (wrap: T) {

    val _wrap = new WeakReference(wrap)

    def wrapped = _wrap.get match {
      case Some(w) => w
      case None => // should never happen 
        throw new IllegalStateException
    }

    override lazy val hashCode = wrapped.hashCode

    override def equals(o: Any): Boolean = o match {
      case LightWeightWrapper(w) => w eq this.wrapped
      case _ => false
    }
  }

所以问题是:在执行同步块期间垃圾收集是否停止?

1 个答案:

答案 0 :(得分:2)

不,垃圾收集仍然在synchronized内部发生。此外,this已经被防止被垃圾收集,因为它在堆栈中,所以你也没有得到任何帮助。

我不确定你在做什么,但我想也许你真的想要使用SoftReference而不是WeakReference。只要所有硬引用都消失,就可以收集仅由WeakReference引用的对象。只有SoftReference引用的对象可以保留,直到VM内存不足为止。