diff --git a/emper/Runtime.cpp b/emper/Runtime.cpp
index e4b189749222f0913beda1faf4059a5c1e805074..ef67ae27031788018398dd3ac850d6543b5c9d31 100644
--- a/emper/Runtime.cpp
+++ b/emper/Runtime.cpp
@@ -67,6 +67,7 @@ using emper::io::IoContext;
 Runtime::Runtime(workerid_t workerCount, RuntimeStrategyFactory& strategyFactory, unsigned int seed)
 		: workerCount(workerCount),
 			workerLatch(workerCount),
+			workerThreadExitLatch(workerCount),
 			strategy(strategyFactory.constructRuntimeStrategy(*this)),
 			scheduler(strategy->getScheduler()),
 			dispatcher(strategy->getDispatcher()),
@@ -229,6 +230,12 @@ auto Runtime::workerLoop(Worker* worker) -> void* {
 
 	// Threads return here if Context::switchToOriginalStack() is called.
 
+	// Ensure that all worker threads exit "at the same" time. Otherwise
+	// it would be possible that one thread is work-stealing,
+	// potentially accessing a work stealing queue of an worker thread
+	// that already exited, causing an invalid access.
+	workerThreadExitLatch.count_down_and_wait();
+
 	return nullptr;
 }
 
diff --git a/emper/Runtime.hpp b/emper/Runtime.hpp
index 24a8c52adc5126119cba00adf683a926f12e862e..621eda413c7a46cd1121d1845b6e25646b873ecf 100644
--- a/emper/Runtime.hpp
+++ b/emper/Runtime.hpp
@@ -51,6 +51,7 @@ class Runtime : public Logger<LogSubsystem::RUNTI> {
 	std::vector<std::function<void(workerid_t)>> newWorkerHooks;
 
 	Latch workerLatch;
+	Latch workerThreadExitLatch;
 
 	RuntimeStrategy* const strategy;
 	Scheduler& scheduler;