ItemizedOverlay с открытым исходным кодом - почему они синхронизировали overlayItem в методе draw?

Этот фрагмент кода взят здесь:

  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, так какой смысл думать, что другие потоки могут изменить это?!

Спасибо!

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 потока может обновлять содержимое списка массивов одновременно.

Другие вопросы по тегам