Index: trunk/src/org/openstreetmap/josm/gui/layer/geoimage/CorrelateGpxWithImages.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/layer/geoimage/CorrelateGpxWithImages.java	(revision 7933)
+++ trunk/src/org/openstreetmap/josm/gui/layer/geoimage/CorrelateGpxWithImages.java	(revision 7935)
@@ -728,5 +728,5 @@
 
                     yLayer.useThumbs = cbShowThumbs.isSelected();
-                    yLayer.loadThumbs();
+                    yLayer.startLoadThumbs();
 
                     // Search whether an other layer has yet defined some bounding box.
Index: trunk/src/org/openstreetmap/josm/gui/layer/geoimage/GeoImageLayer.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/layer/geoimage/GeoImageLayer.java	(revision 7933)
+++ trunk/src/org/openstreetmap/josm/gui/layer/geoimage/GeoImageLayer.java	(revision 7935)
@@ -18,7 +18,4 @@
 import java.awt.event.MouseEvent;
 import java.awt.image.BufferedImage;
-import java.awt.datatransfer.Clipboard;
-import java.awt.datatransfer.StringSelection;
-import java.awt.Toolkit;
 import java.beans.PropertyChangeEvent;
 import java.beans.PropertyChangeListener;
@@ -38,4 +35,6 @@
 import java.util.Set;
 import java.util.TimeZone;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
 
 import javax.swing.Action;
@@ -78,4 +77,5 @@
 import com.drew.metadata.exif.ExifIFD0Directory;
 import com.drew.metadata.exif.GpsDirectory;
+import java.util.concurrent.ThreadFactory;
 
 /**
@@ -93,6 +93,15 @@
 
     boolean useThumbs = false;
+    ExecutorService thumbusLoaderExecutor = Executors.newSingleThreadExecutor(new ThreadFactory() {
+        @Override
+        public Thread newThread(Runnable r) {
+            Thread t = new Thread(r);
+            t.setPriority(Thread.MIN_PRIORITY);
+            return t;
+        }
+    });
     ThumbsLoader thumbsloader;
-    boolean thumbsLoaded = false;
+    boolean thumbsLoaderRunning = false;
+    volatile boolean thumbsLoaded = false;
     private BufferedImage offscreenBuffer;
     boolean updateOffscreenBuffer = true;
@@ -331,4 +340,5 @@
         entries.add(SeparatorLayerAction.INSTANCE);
         entries.add(new CorrelateGpxWithImages(this));
+        entries.add(new ShowThumbnailAction(this));
         if (!menuAdditions.isEmpty()) {
             entries.add(SeparatorLayerAction.INSTANCE);
@@ -372,4 +382,9 @@
     public void mergeFrom(Layer from) {
         GeoImageLayer l = (GeoImageLayer) from;
+
+        // Stop to load thumbnails on both layers.  Thumbnail loading will continue the next time
+        // the layer is painted.
+        stopLoadThumbs();
+        l.stopLoadThumbs();
 
         ImageEntry selected = null;
@@ -440,5 +455,5 @@
         if (useThumbs) {
             if (!thumbsLoaded) {
-                loadThumbs();
+                startLoadThumbs();
             }
 
@@ -989,7 +1004,5 @@
             public void layerRemoved(Layer oldLayer) {
                 if (oldLayer == GeoImageLayer.this) {
-                    if (thumbsloader != null) {
-                        thumbsloader.stop = true;
-                    }
+                    stopLoadThumbs();
                     Main.map.mapView.removeMouseListener(mouseAdapter);
                     MapFrame.removeMapModeChangeListener(mapModeListener);
@@ -1017,12 +1030,36 @@
     }
 
-    public void loadThumbs() {
-        if (useThumbs && !thumbsLoaded) {
-            thumbsLoaded = true;
+    /**
+     * Start to load thumbnails.
+     */
+    public synchronized void startLoadThumbs() {
+        if (useThumbs && !thumbsLoaded && !thumbsLoaderRunning) {
+            stopLoadThumbs();
             thumbsloader = new ThumbsLoader(this);
-            Thread t = new Thread(thumbsloader);
-            t.setPriority(Thread.MIN_PRIORITY);
-            t.start();
-        }
+            thumbusLoaderExecutor.submit(thumbsloader);
+            thumbsLoaderRunning = true;
+        }
+    }
+
+    /**
+     * Stop to load thumbnails.
+     * 
+     * Can be called at any time to make sure that the
+     * thumbnail loader is stopped.
+     */
+    public synchronized void stopLoadThumbs() {
+        if (thumbsloader != null) {
+            thumbsloader.stop = true;
+        }
+        thumbsLoaderRunning = false;
+    }
+
+    /**
+     * Called to signal that the loading of thumbnails has finished.
+     * 
+     * Usually called from {@link ThumbsLoader} in another thread.
+     */
+    public void thumbsLoaded() {
+        thumbsLoaded = true;
     }
 
@@ -1076,5 +1113,7 @@
         this.useThumbs = useThumbs;
         if (useThumbs && !thumbsLoaded) {
-            loadThumbs();
+            startLoadThumbs();
+        } else if (!useThumbs) {
+            stopLoadThumbs();
         }
     }
Index: trunk/src/org/openstreetmap/josm/gui/layer/geoimage/ShowThumbnailAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/layer/geoimage/ShowThumbnailAction.java	(revision 7935)
+++ trunk/src/org/openstreetmap/josm/gui/layer/geoimage/ShowThumbnailAction.java	(revision 7935)
@@ -0,0 +1,69 @@
+// License: GPL. See LICENSE file for details.
+package org.openstreetmap.josm.gui.layer.geoimage;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+import java.awt.Component;
+import java.awt.event.ActionEvent;
+import java.util.List;
+import javax.swing.AbstractAction;
+import javax.swing.JCheckBoxMenuItem;
+
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.gui.layer.Layer;
+import org.openstreetmap.josm.gui.layer.Layer.LayerAction;
+import org.openstreetmap.josm.tools.ImageProvider;
+
+/**
+ * Toggle the image display between thumbnails and symbols.
+ * @since tbd
+ */
+public class ShowThumbnailAction extends AbstractAction implements LayerAction {
+
+    private final GeoImageLayer layer;
+
+    /**
+     * Constructs a new {@code ToggleGeoImageThumbAction} action.
+     * @param layer image layer
+     */
+    public ShowThumbnailAction(GeoImageLayer layer) {
+        super(tr("Show thumbnails"), ImageProvider.get("dialogs/geoimage/togglegit"));
+        putValue(SHORT_DESCRIPTION, tr("Show image thumbnails instead of icons."));
+        this.layer = layer;
+    }
+
+    /**
+     * This is called after the menu entry was selected.
+     * @param arg0 action event
+     */
+    @Override
+    public void actionPerformed(ActionEvent arg0) {
+        layer.setUseThumbs(!layer.isUseThumbs());
+        Main.map.mapView.repaint();
+    }
+
+    /**
+     * Check if there is any suitable image to be toggled.
+     * @param layer image layer
+     * @return {@code true} if there are images to be toggled,
+     *         {@code false} otherwise
+     */
+    private static boolean enabled(GeoImageLayer layer) {
+        return !layer.data.isEmpty();
+    }
+
+    /** Create actual menu entry and define if it is enabled or not. */
+    @Override
+    public Component createMenuComponent() {
+        JCheckBoxMenuItem toggleItem = new JCheckBoxMenuItem(this);
+        toggleItem.setEnabled(enabled(layer));
+        toggleItem.setState(layer.isUseThumbs());
+        return toggleItem;
+    }
+
+    /** Check if the current layer is supported. */
+    @Override
+    public boolean supportLayers(List<Layer> layers) {
+        return layers.size() == 1 && layers.get(0) instanceof GeoImageLayer;
+    }
+}
Index: trunk/src/org/openstreetmap/josm/gui/layer/geoimage/ThumbsLoader.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/layer/geoimage/ThumbsLoader.java	(revision 7933)
+++ trunk/src/org/openstreetmap/josm/gui/layer/geoimage/ThumbsLoader.java	(revision 7935)
@@ -17,5 +17,5 @@
     public static final int maxSize = 120;
     public static final int minSize = 22;
-    volatile boolean stop = false;
+    public volatile boolean stop = false;
     List<ImageEntry> data;
     GeoImageLayer layer;
@@ -51,4 +51,5 @@
             }
         }
+        layer.thumbsLoaded();
         layer.updateOffscreenBuffer = true;
         Main.map.mapView.repaint();
Index: trunk/src/org/openstreetmap/josm/gui/progress/ProgressMonitorExecutor.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/progress/ProgressMonitorExecutor.java	(revision 7933)
+++ trunk/src/org/openstreetmap/josm/gui/progress/ProgressMonitorExecutor.java	(revision 7935)
@@ -8,4 +8,10 @@
 import org.openstreetmap.josm.Main;
 
+/**
+ * Executor that displays the progress monitor to the user.
+ * 
+ * Similar to Executors.newSingleThreadExecutor(), but displays the
+ * progress monitor whenever a new task is executed.
+ */
 public class ProgressMonitorExecutor extends ThreadPoolExecutor {
 
