1

此代码片段取自此处

  protected void drawOverlayBitmap(Canvas canvas, Point drawPosition, Projection projection,
      byte drawZoomLevel) {
    synchronized (this.visibleItems) {
      // erase the list of visible items
      this.visibleItems.clear();

      this.numberOfItems = size();
      if (this.numberOfItems < 1) {
        // no items to draw
        return;
      }

      // draw the overlay items
      for (int itemIndex = 0; itemIndex < this.numberOfItems; ++itemIndex) {
        // get the current item
        this.overlayItem = createItem(itemIndex);

        synchronized (this.overlayItem) {
          // check if the item has a position
          if (this.overlayItem.getPoint() == null) {
            continue;
          }

          // make sure that the cached item position is valid
          if (drawZoomLevel != this.overlayItem.cachedZoomLevel) {
            this.overlayItem.cachedMapPosition = projection.toPoint(
                this.overlayItem.getPoint(),
                this.overlayItem.cachedMapPosition, drawZoomLevel);
            this.overlayItem.cachedZoomLevel = drawZoomLevel;
          }

          // calculate the relative item position on the display
          this.itemPosition.x = this.overlayItem.cachedMapPosition.x - drawPosition.x;
          this.itemPosition.y = this.overlayItem.cachedMapPosition.y - drawPosition.y;

          // get the correct marker for the item
          if (this.overlayItem.getMarker() == null) {
            if (this.defaultMarker == null) {
              // no marker to draw the item
              continue;
            }
            this.itemMarker = this.defaultMarker;
          } else {
            this.itemMarker = this.overlayItem.getMarker();
          }

          // get the position of the marker
          this.markerBounds = this.itemMarker.copyBounds();

          // calculate the bounding box of the marker
          this.left = this.itemPosition.x + this.markerBounds.left;
          this.right = this.itemPosition.x + this.markerBounds.right;
          this.top = this.itemPosition.y + this.markerBounds.top;
          this.bottom = this.itemPosition.y + this.markerBounds.bottom;

          // check if the bounding box of the marker intersects with the canvas
          if (this.right >= 0 && this.left <= canvas.getWidth() && this.bottom >= 0
              && this.top <= canvas.getHeight()) {
            // set the position of the marker
            this.itemMarker.setBounds(this.left, this.top, this.right, this.bottom);

            // draw the item marker on the canvas
            this.itemMarker.draw(canvas);

            // restore the position of the marker
            this.itemMarker.setBounds(this.markerBounds);

            // add the current item index to the list of visible items
            this.visibleItems.add(Integer.valueOf(itemIndex));
          }
        }
      }
    }
  }

现在我发现很难得到的是他们为什么要同步overlayItem,这对我来说毫无意义,我认为它的冗余有几个原因,最重要的是,在同步块中,有一个参考OverlayItem 类的最后一个成员是 GeoPoint,那么认为其他线程可以改变这一点有什么意义?!

谢谢!

4

1 回答 1

-1

对象市场最终将对象标记为常量,例如具有:

final ArrayList<Integer> visibleItems;

因此,您不允许将另一个对象分配给visibleItems,因为visibleItems标记为final

例如,尝试在下面的代码中执行类似操作,将导致编译错误:

ArrayList<Integer> anotherArray = new ArrayList<Integer>();
visibleItems = anotherArray; //Compile error.

但是,这并不意味着数组列表包含的所有元素也都标记为final。不。

一个线程可能会添加新元素,另一个线程可能会删除一些元素:

anotherArray.add(2);
anotherArray.add(5);
//........

anotherArray.remove(5);

这就是为什么要保留变量syncronized,以确保不超过 1 个线程可以同时更新数组列表的内容。

于 2012-08-17T11:32:37.217 回答