diff --git a/dumux/discretization/basegridgeometry.hh b/dumux/discretization/basegridgeometry.hh
index 7ffc3dfb9d17443bfaccc1bd2d83a90e07cf3895..c14853150c997a2b0ffaa493ad1ef9ec912aa453 100644
--- a/dumux/discretization/basegridgeometry.hh
+++ b/dumux/discretization/basegridgeometry.hh
@@ -26,6 +26,7 @@
 
 #include <utility>
 #include <type_traits>
+#include <mutex>
 
 #include <dune/grid/common/mcmgmapper.hh>
 
@@ -73,7 +74,7 @@ public:
 
     /*!
      * \ingroup Discretization
-     * \brief Constructor computes the bouding box of the entire domain, for e.g. setting boundary conditions
+     * \brief Constructor computes the bounding box of the entire domain, for e.g. setting boundary conditions
      * \param gridView the grid view on which to construct the grid geometry
      */
     BaseGridGeometry(const GridView& gridView)
@@ -149,11 +150,14 @@ public:
      */
     const BoundingBoxTree& boundingBoxTree() const
     {
-        if(!boundingBoxTree_)
+        if (!boundingBoxTree_)
         {
-            elementMap(); // make sure the element map is built
-            boundingBoxTree_ = std::make_unique<BoundingBoxTree>
-                                    ( std::make_shared<ElementSet>(gridView_, elementMapper(), elementMap_) );
+            std::scoped_lock{ boundingBoxTreeMutex_ };
+            if (!boundingBoxTree_)
+                elementMap(); // make sure the element map is built
+                boundingBoxTree_ = std::make_unique<BoundingBoxTree>(
+                    std::make_shared<ElementSet>(gridView_, elementMapper(), elementMap_)
+                );
         }
 
         return *boundingBoxTree_;
@@ -164,8 +168,12 @@ public:
      */
     const ElementMap& elementMap() const
     {
-        if(!elementMap_)
-            elementMap_ = std::make_shared<ElementMap>(gridView_.grid(), elementMapper_);
+        if (!elementMap_)
+        {
+            std::scoped_lock{ elementMapMutex_ };
+            if (!elementMap_)
+                elementMap_ = std::make_shared<ElementMap>(gridView_.grid(), elementMapper_);
+        }
 
         return *elementMap_;
     }
@@ -222,7 +230,7 @@ private:
             return VertexMapper(gridView);
     }
 
-    //! Compute the bouding box of the entire domain, for e.g. setting boundary conditions
+    //! Compute the bounding box of the entire domain, for e.g. setting boundary conditions
     void computeGlobalBoundingBox_()
     {
         // calculate the bounding box of the local partition of the grid view
@@ -261,7 +269,7 @@ private:
         else
             Deprecated::update(vertexMapper_);
 
-        //! Compute the bouding box of the entire domain, for e.g. setting boundary conditions
+        //! Compute the bounding box of the entire domain, for e.g. setting boundary conditions
         computeGlobalBoundingBox_();
 
         //! reset bounding box tree and the element map until requested the next time
@@ -276,11 +284,13 @@ private:
     ElementMapper elementMapper_;
     VertexMapper vertexMapper_;
 
-    //! the bounding box tree of the grid view for effecient element intersections
+    //! the bounding box tree of the grid view for efficient element intersections
     mutable std::unique_ptr<BoundingBoxTree> boundingBoxTree_;
+    mutable std::mutex boundingBoxTreeMutex_;
 
     //! a map from element index to elements (needed in the bounding box tree and for assembling cell-centered discretization)
     mutable std::shared_ptr<ElementMap> elementMap_;
+    mutable std::mutex elementMapMutex_;
 
     //! the bounding box of the whole domain
     GlobalCoordinate bBoxMin_;