The synchronized here is VERY important.  If missing, the mapDatabase read gets corrupted by multiple threads reading the file at once.
5369
public synchronized Drawable renderTile(final long pMapTileIndex) {

        Tile tile = new Tile(MapTileIndex.getX(pMapTileIndex), MapTileIndex.getY(pMapTileIndex), (byte) MapTileIndex.getZoom(pMapTileIndex), 256);
        model.setFixedTileSize(256);

        //You could try something like this to load a custom theme
        //try{
        //	jobTheme = new ExternalRenderTheme(themeFile);
        //}
        //catch(Exception e){
        //	jobTheme = InternalRenderTheme.OSMARENDER;
        //}


        if (mapDatabase==null)
            return null;
        try {
            //Draw the tile
            RendererJob mapGeneratorJob = new RendererJob(tile, mapDatabase, theme, model, scale, false, false);
            AndroidTileBitmap bmp = (AndroidTileBitmap) renderer.executeJob(mapGeneratorJob);
            if (bmp != null)
                return new BitmapDrawable(AndroidGraphicFactory.getBitmap(bmp));
        } catch (Exception ex) {
            Log.d(IMapView.LOGTAG, "###################### Mapsforge tile generation failed", ex);
        }
        //Make the bad tile easy to spot
        Bitmap bitmap = Bitmap.createBitmap(TILE_SIZE_PIXELS, TILE_SIZE_PIXELS, Bitmap.Config.RGB_565);
        bitmap.eraseColor(Color.YELLOW);
        return new BitmapDrawable(bitmap);
    }
1341762
@Override
  public boolean nextKeyValue()
      throws IOException, InterruptedException {
    currentValue = null;

    // Check if we already have a reader in-progress.
    if (delegateReader != null) {
      if (delegateReader.nextKeyValue()) {
        populateCurrentKeyValue();
        return true;
      } else {
        delegateReader.close();
        delegateReader = null;
      }
    }

    boolean needRefresh = !isNextFileReady() && shouldExpectMoreFiles();
    while (needRefresh) {
      logger.atFine().log("No files available, but more are expected; refreshing...");
      refreshFileList();
      needRefresh = !isNextFileReady() && shouldExpectMoreFiles();
      if (needRefresh) {
        logger.atFine().log("No new files found, sleeping before trying again...");
        try {
          sleeper.sleep(pollIntervalMs);
          context.progress();
        } catch (InterruptedException ie) {
          logger.atWarning().withCause(ie).log("Interrupted while sleeping.");
        }
      }
    }

    if (isNextFileReady()) {
      // Open the file and see if it's the 0-record end of dataset marker:
      FileStatus newFile = moveToNextFile();
      logger.atInfo().log(
          "Moving to next file '%s' which has %s bytes. Records read so far: %s",
          newFile.getPath(), newFile.getLen(), recordsRead);

      InputSplit split = new FileSplit(newFile.getPath(), 0, newFile.getLen(), new String[0]);
      delegateReader = delegateRecordReaderFactory.createDelegateRecordReader(
          split, context.getConfiguration());
      delegateReader.initialize(split, context);
      if (!delegateReader.nextKeyValue()) {
        // we found the end of dataset marker.
        setEndFileMarkerFile(newFile.getPath().getName());
        return nextKeyValue();
      } else {
        populateCurrentKeyValue();
        return true;
      }
    }

    Preconditions.checkState(
        !shouldExpectMoreFiles(),
        "Should not have exited the refresh loop shouldExpectMoreFiles = true "
            + "and no files ready to read.");

    // No files ready and we shouldn't expect any more.
    return false;
  }
291105
private synchronized Map<String, JsonObject> getAssetMap() throws IOException {
        if (!file.canRead()) {
            throw new IOException("Cannot read repository file: " + file.getAbsolutePath());
        } else if (assets == null || file.lastModified() != fileLastModified || file.length() != fileLastSize) {
            // Re-read the file if either we've never read it or it's changed length since we last read it
            assets = null;
            fileLastModified = file.lastModified();
            fileLastSize = file.length();

            idCounter = new AtomicInteger(1);
            assets = new HashMap<String, JsonObject>();
            try (JsonReader reader = Json.createReader(new FileInputStream(file))) {
                JsonArray assetList = reader.readArray();
                for (JsonValue val : assetList) {
                    String id = Integer.toString(idCounter.getAndIncrement());
                    if (val.getValueType() == ValueType.OBJECT) {
                        assets.put(id, (JsonObject) val);
                    }
                }
            }
        }

        return assets;

    }
1278074
private void readMultiMapKeys(XMLEventReader reader, MultiValueMap<String> map)
            throws XMLStreamException, JournalException {
        while (true) {
            XMLEvent event2 = reader.nextTag();
            if (isStartTagEvent(event2, QNAME_TAG_MULTI_VALUE_MAP_KEY)) {
                // if we find a key tag, get the name
                String key =
                        getRequiredAttributeValue(event2.asStartElement(),
                                                  QNAME_ATTR_NAME);
                // read as many values as we find.
                String[] values = readMultiMapValuesForKey(reader);
                // store in the map
                storeInMultiMap(map, key, values);
            } else if (isEndTagEvent(event2, QNAME_TAG_MULTI_VALUE_MAP)) {
                break;
            } else {
                throw getNotNextMemberOrEndOfGroupException(QNAME_TAG_MULTI_VALUE_MAP,
                                                            QNAME_TAG_MULTI_VALUE_MAP_KEY,
                                                            event2);
            }
        }
    }
1271425
@Override
	public void read(final DataInput in) throws IOException {
		int size = in.readInt();
		this.map.clear();

		try {
			for (; size > 0; size--) {
				final K key = this.keyClass.newInstance();
				final V val = this.valueClass.newInstance();
				key.read(in);
				val.read(in);
				this.map.put(key, val);
			}
		} catch (final InstantiationException e) {
			throw new RuntimeException(e);
		} catch (final IllegalAccessException e) {
			throw new RuntimeException(e);
		}
	}
1293103
long recordRead(int bufferIndex, Node<K, V> node) {
        // The location in the buffer is chosen in a racy fashion as the increment
        // is not atomic with the insertion. This means that concurrent reads can
        // overlap and overwrite one another, resulting in a lossy buffer.
        final AtomicLong counter = readBufferWriteCount[bufferIndex];
        final long writeCount = counter.get();
        counter.lazySet(writeCount + 1);

        final int index = (int) (writeCount & READ_BUFFER_INDEX_MASK);
        readBuffers[bufferIndex][index].lazySet(node);

        return writeCount;
    }
855460
private boolean isMultiChunked(final String filename) {
      final FileCacheKey fileCacheKey = new FileCacheKey(indexName, filename, affinitySegmentId);
      final FileMetadata fileMetadata = metadataCache.get(fileCacheKey);
      if (fileMetadata==null) {
         //This might happen under high load when the metadata is being written
         //using putAsync; in such case we return true as it's the safest option.
         //Skipping the readlocks is just a performance optimisation, and this
         //condition is extremely rare.
         return true;
      }
      else {
         return fileMetadata.isMultiChunked();
      }
   }
378281
private synchronized void flushData() {
        BufferedWriter writer = null;
        try {
            writer = new BufferedWriter(new FileWriter(new File(this.inputPath)));
            for(String key: this.metadataMap.keySet()) {
                writer.write(NEW_PROPERTY_SEPARATOR + key.toString() + "]" + NEW_LINE);
                writer.write(this.metadataMap.get(key).toString());
                writer.write("" + NEW_LINE + "" + NEW_LINE);
            }
            writer.flush();
        } catch(IOException e) {
            logger.error("IO exception while flushing data to file backed storage: "
                         + e.getMessage());
        }

        try {
            if(writer != null)
                writer.close();
        } catch(Exception e) {
            logger.error("Error while flushing data to file backed storage: " + e.getMessage());
        }
    }
886105
@Override
	public int read() throws IOException {
		// Read from the queue
		synchronized(file) {
			while(true) {
				long len=file.getLength();
				if(len>=1) {
					long pos=file.getFirstIndex();
					file.file.seek(pos+16);
					int b=file.file.read();
					if(b==-1) throw new EOFException("Unexpected EOF");
					addStats(1);
					long newFirstIndex=pos+1;
					while(newFirstIndex>=file.maxFifoLength) newFirstIndex-=file.maxFifoLength;
					file.setFirstIndex(newFirstIndex);
					file.setLength(len-1);
					file.notify();
					return b;
				}
				try {
					file.wait();
				} catch(InterruptedException err) {
					InterruptedIOException ioErr=new InterruptedIOException();
					ioErr.initCause(err);
					throw ioErr;
				}
			}
		}
	}
1029462
synchronized int read(byte[] data) {
        this.header = getHeaderParser().setData(data).parseHeader();
        if (data != null) {
            setData(header, data);
        }

        return status;
    }
494432
@SuppressWarnings("unchecked")
  @Override
  public D readRecordImpl(D reuse) throws DataRecordException, IOException {
    if (this.shutdownRequested.get()) {
      return null;
    }

    long readStartTime = System.nanoTime();

    while (!allPartitionsFinished()) {
      if (currentPartitionFinished()) {
        moveToNextPartition();
        continue;
      }
      if (this.messageIterator == null || !this.messageIterator.hasNext()) {
        try {
          long fetchStartTime = System.nanoTime();
          this.messageIterator = fetchNextMessageBuffer();
          this.currentPartitionFetchMessageBufferTime += System.nanoTime() - fetchStartTime;
        } catch (Exception e) {
          LOG.error(String.format("Failed to fetch next message buffer for partition %s. Will skip this partition.",
              getCurrentPartition()), e);
          moveToNextPartition();
          continue;
        }
        if (this.messageIterator == null || !this.messageIterator.hasNext()) {
          moveToNextPartition();
          continue;
        }
      }
      while (!currentPartitionFinished()) {
        if (!this.messageIterator.hasNext()) {
          break;
        }

        KafkaConsumerRecord nextValidMessage = this.messageIterator.next();

        // Even though we ask Kafka to give us a message buffer starting from offset x, it may
        // return a buffer that starts from offset smaller than x, so we need to skip messages
        // until we get to x.
        if (nextValidMessage.getOffset() < this.nextWatermark.get(this.currentPartitionIdx)) {
          continue;
        }

        this.nextWatermark.set(this.currentPartitionIdx, nextValidMessage.getNextOffset());
        try {
          // track time for decode/convert depending on the record type
          long decodeStartTime = System.nanoTime();

          D record = decodeKafkaMessage(nextValidMessage);

          this.currentPartitionDecodeRecordTime += System.nanoTime() - decodeStartTime;
          this.currentPartitionRecordCount++;
          this.currentPartitionTotalSize += nextValidMessage.getValueSizeInBytes();
          this.currentPartitionReadRecordTime += System.nanoTime() - readStartTime;
          this.currentPartitionLastSuccessfulRecord = record;
          return record;
        } catch (Throwable t) {
          this.errorPartitions.add(this.currentPartitionIdx);
          this.undecodableMessageCount++;
          if (shouldLogError()) {
            LOG.error(String.format("A record from partition %s cannot be decoded.", getCurrentPartition()), t);
          }
          incrementErrorCount();
        }
      }
    }
    LOG.info("Finished pulling topic " + this.topicName);

    this.currentPartitionReadRecordTime += System.nanoTime() - readStartTime;
    return null;
  }
51625
@Override
	public void read(final DataInput in) throws IOException {

		synchronized (this.confData) {

			final int numberOfProperties = in.readInt();

			for (int i = 0; i < numberOfProperties; i++) {
				final String key = StringRecord.readString(in);
				final String value = StringRecord.readString(in);
				this.confData.put(key, value);
			}
		}
	}
347579
boolean hasNext() throws DataSourceReadException {
        if (!hasNextComputed) {
            boolean stayInLoop;
            do {
                stayInLoop = false;
                /*
                 * Prior to reading the first iterator, we loop through all of
                 * the iterators to determine the minimum keyId. The minimum
                 * keyId, stored in currentMin, is used for data retrieval. The
                 * value of currentMin will be null if there is no data to
                 * retrieve.
                 */
                if (i == 0) {
                    this.currentMin = null;
                    for (DataStreamingEvent<E> elt : this.currentElt) {
                        currentMin = min(elt);
                    }
                }
                /*
                 * If there is no data to retrieve, we'll return false. If there
                 * is data to retrieve, we'll loop through the iterators and
                 * pull data for the current keyId, which is the keyId field of
                 * currentMin. If there's no data for the current keyId, this
                 * should loop through all of the iterators until their ends,
                 * and set hasNext to false.
                 */
                if (currentMin == null) {
                    this.hasNext = false;
                } else {
                    int n = this.currentElt.size();
                    for (; i < n; i++) {
                        DataStreamingEvent<E> elt = this.currentElt.get(i);
                        if (elt != null && elt.getKeyId().equals(
                                this.currentMin != null 
                                ? this.currentMin.getKeyId() : null)) {
                            this.result = elt;
                            this.nextKeyId = elt.getKeyId();
                            advance(i);
                            i++;
                            break;
                        }
                    }
                    if (this.i == n && this.result == null) {
                        this.i = 0;
                        stayInLoop = true;
                    }
                }
            } while (this.hasNext && stayInLoop);
            this.hasNextComputed = true;
        }
        return hasNext;
    }
825644
@Override
    public void sync( NativeObject jsRWB, Object data ) {
        synchronizationPoint(jsRWB, null, data);
    }
504864
private void writeSyncList() throws CmsException {

        // the sync list file in the server file system
        File syncListFile;
        syncListFile = new File(m_destinationPathInRfs, SYNCLIST_FILENAME);

        // prepare the streams to write the data
        FileOutputStream fOut = null;
        PrintWriter pOut = null;
        try {
            fOut = new FileOutputStream(syncListFile);
            pOut = new PrintWriter(fOut);
            pOut.println(CmsSynchronizeList.getFormatDescription());

            // get all keys from the hash map and make an iterator on it
            Iterator<CmsSynchronizeList> values = m_newSyncList.values().iterator();
            // loop through all values and write them to the sync list file in
            // a human readable format
            while (values.hasNext()) {
                CmsSynchronizeList sync = values.next();
                //fOut.write(sync.toString().getBytes());
                pOut.println(sync.toString());
            }
        } catch (IOException e) {
            throw new CmsDbIoException(Messages.get().container(Messages.ERR_IO_WRITE_SYNCLIST_0), e);
        } finally {
            // close all streams that were used
            try {
                if (pOut != null) {
                    pOut.flush();
                    pOut.close();
                }
                if (fOut != null) {
                    fOut.flush();
                    fOut.close();
                }
            } catch (IOException e) {
                // ignore
            }
        }
    }
1169507
@Override
    public void sync(List<Dml> dmls) {
        if (dmls == null || dmls.isEmpty()) {
            return;
        }
        try {
            rdbSyncService.sync(mappingConfigCache, dmls, envProperties);
            rdbMirrorDbSyncService.sync(dmls);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
63632
@Override
	public int read(byte[] b, int off, int len) throws IOException {
		// Read from the queue
		synchronized(file) {
			while(true) {
				long fileLen=file.getLength();
				if(fileLen>=1) {
					long pos=file.getFirstIndex();
					file.file.seek(pos+16);
					int readSize=fileLen>len?len:(int)fileLen;
					// When at the end of the file, read the remaining bytes
					if((pos+readSize)>file.maxFifoLength) readSize=(int)(file.maxFifoLength-pos);

					// Read as many bytes as currently available
					int totalRead=file.file.read(b, off, readSize);
					if(totalRead==-1) throw new EOFException("Unexpected EOF");
					addStats(totalRead);
					long newFirstIndex=pos+totalRead;
					while(newFirstIndex>=file.maxFifoLength) newFirstIndex-=file.maxFifoLength;
					file.setFirstIndex(newFirstIndex);
					file.setLength(fileLen-totalRead);
					file.notify();
					return totalRead;
				}
				try {
					file.wait();
				} catch(InterruptedException err) {
					InterruptedIOException ioErr=new InterruptedIOException();
					ioErr.initCause(err);
					throw ioErr;
				}
			}
		}
	}