diff --git a/statsd/src/StatsService.cpp b/statsd/src/StatsService.cpp
index 86c2de8..afd5194 100644
--- a/statsd/src/StatsService.cpp
+++ b/statsd/src/StatsService.cpp
@@ -234,6 +234,7 @@
 }
 
 StatsService::~StatsService() {
+    onStatsdInitCompletedHandlerTermination();
     if (mEventQueue != nullptr) {
         stopReadingLogs();
         mLogsReaderThread->join();
@@ -1062,6 +1063,7 @@
 Status StatsService::informDeviceShutdown() {
     ENFORCE_UID(AID_SYSTEM);
     VLOG("StatsService::informDeviceShutdown");
+    onStatsdInitCompletedHandlerTermination();
     int64_t elapsedRealtimeNs = getElapsedRealtimeNs();
     int64_t wallClockNs = getWallClockNs();
     mProcessor->WriteDataToDisk(DEVICE_SHUTDOWN, FAST, elapsedRealtimeNs, wallClockNs);
@@ -1115,7 +1117,14 @@
         // This function is called from a dedicated thread without holding locks, so sleeping is ok.
         // See MultiConditionTrigger::markComplete() executorThread for details
         // For more details see http://b/277958338
-        std::this_thread::sleep_for(std::chrono::seconds(mInitEventDelaySecs));
+
+        std::unique_lock<std::mutex> lk(mStatsdInitCompletedHandlerTerminationFlagMutex);
+        if (mStatsdInitCompletedHandlerTerminationFlag.wait_for(
+                    lk, std::chrono::seconds(mInitEventDelaySecs),
+                    [this] { return mStatsdInitCompletedHandlerTerminationRequested; })) {
+            VLOG("StatsService::onStatsdInitCompleted() Early termination is requested");
+            return;
+        }
     }
 
     mProcessor->onStatsdInitCompleted(getElapsedRealtimeNs());
@@ -1132,6 +1141,7 @@
 
 void StatsService::Terminate() {
     ALOGI("StatsService::Terminating");
+    onStatsdInitCompletedHandlerTermination();
     if (mProcessor != nullptr) {
         int64_t elapsedRealtimeNs = getElapsedRealtimeNs();
         int64_t wallClockNs = getWallClockNs();
@@ -1142,6 +1152,14 @@
     }
 }
 
+void StatsService::onStatsdInitCompletedHandlerTermination() {
+    {
+        std::unique_lock<std::mutex> lk(mStatsdInitCompletedHandlerTerminationFlagMutex);
+        mStatsdInitCompletedHandlerTerminationRequested = true;
+    }
+    mStatsdInitCompletedHandlerTerminationFlag.notify_all();
+}
+
 // Test only interface!!!
 void StatsService::OnLogEvent(LogEvent* event) {
     mProcessor->OnLogEvent(event);
@@ -1400,6 +1418,7 @@
 void StatsService::statsCompanionServiceDiedImpl() {
     ALOGW("statscompanion service died");
     StatsdStats::getInstance().noteSystemServerRestart(getWallClockSec());
+    onStatsdInitCompletedHandlerTermination();
     if (mProcessor != nullptr) {
         ALOGW("Reset statsd upon system server restarts.");
         int64_t systemServerRestartNs = getElapsedRealtimeNs();
diff --git a/statsd/src/StatsService.h b/statsd/src/StatsService.h
index 0a167dd..6a5d954 100644
--- a/statsd/src/StatsService.h
+++ b/statsd/src/StatsService.h
@@ -416,10 +416,15 @@
     void onStatsdInitCompleted();
 
     /*
-     *  This method is used to stop log reader thread.
+     * This method is used to stop log reader thread.
      */
     void stopReadingLogs();
 
+    /*
+     * Notify async StatsdInitCompleted handler about termination event
+     */
+    void onStatsdInitCompletedHandlerTermination();
+
     std::atomic<bool> mIsStopRequested = false;
 
     /**
@@ -468,6 +473,14 @@
 
     std::unique_ptr<std::thread> mLogsReaderThread;
 
+    std::condition_variable mStatsdInitCompletedHandlerTerminationFlag;
+    std::mutex mStatsdInitCompletedHandlerTerminationFlagMutex;
+    /**
+     * @brief Used to communicated early termination request to onStatsdInitCompleted Handler
+     * @see onStatsdInitCompleted
+     */
+    bool mStatsdInitCompletedHandlerTerminationRequested = false;
+
     MultiConditionTrigger mBootCompleteTrigger;
     static const inline string kBootCompleteTag = "BOOT_COMPLETE";
     static const inline string kUidMapReceivedTag = "UID_MAP";
diff --git a/statsd/src/utils/MultiConditionTrigger.cpp b/statsd/src/utils/MultiConditionTrigger.cpp
index d9ad25b..e574969 100644
--- a/statsd/src/utils/MultiConditionTrigger.cpp
+++ b/statsd/src/utils/MultiConditionTrigger.cpp
@@ -14,11 +14,10 @@
  * limitations under the License.
  */
 #define STATSD_DEBUG false  // STOPSHIP if true
+#include "Log.h"
 
 #include "MultiConditionTrigger.h"
 
-#include <thread>
-
 namespace android {
 namespace os {
 namespace statsd {
@@ -33,8 +32,7 @@
       mTrigger(std::move(trigger)),
       mCompleted(mRemainingConditionNames.empty()) {
     if (mCompleted) {
-        std::thread executorThread([this] { mTrigger(); });
-        executorThread.detach();
+        startExecutorThread();
     }
 }
 
@@ -50,10 +48,21 @@
         doTrigger = mCompleted;
     }
     if (doTrigger) {
-        std::thread executorThread([this] { mTrigger(); });
-        executorThread.detach();
+        startExecutorThread();
     }
 }
+
+void MultiConditionTrigger::startExecutorThread() {
+    mExecutorThread = std::make_unique<std::thread>([this] { mTrigger(); });
+}
+
+MultiConditionTrigger::~MultiConditionTrigger() {
+    if (mExecutorThread != nullptr && mExecutorThread->joinable()) {
+        VLOG("MultiConditionTrigger waiting on execution thread termination");
+        mExecutorThread->join();
+    }
+}
+
 }  // namespace statsd
 }  // namespace os
 }  // namespace android
diff --git a/statsd/src/utils/MultiConditionTrigger.h b/statsd/src/utils/MultiConditionTrigger.h
index 7a09119..773197d 100644
--- a/statsd/src/utils/MultiConditionTrigger.h
+++ b/statsd/src/utils/MultiConditionTrigger.h
@@ -19,6 +19,7 @@
 
 #include <mutex>
 #include <set>
+#include <thread>
 
 namespace android {
 namespace os {
@@ -27,8 +28,8 @@
 /**
  * This class provides a utility to wait for a set of named conditions to occur.
  *
- * It will execute the trigger runnable in a detached thread once all conditions have been marked
- * true.
+ * It will execute the trigger runnable in a separate thread (which will be joined at instance
+ * destructor time) once all conditions have been marked true.
  */
 class MultiConditionTrigger {
 public:
@@ -37,16 +38,22 @@
 
     MultiConditionTrigger(const MultiConditionTrigger&) = delete;
     MultiConditionTrigger& operator=(const MultiConditionTrigger&) = delete;
+    ~MultiConditionTrigger();
 
     // Mark a specific condition as true. If this condition has called markComplete already or if
     // the event was not specified in the constructor, the function is a no-op.
     void markComplete(const std::string& conditionName);
 
 private:
+    void startExecutorThread();
+
     mutable std::mutex mMutex;
     std::set<std::string> mRemainingConditionNames;
     std::function<void()> mTrigger;
     bool mCompleted;
+    std::unique_ptr<std::thread> mExecutorThread;
+
+    FRIEND_TEST(MultiConditionTriggerTest, TestCountDownCalledBySameEventName);
 };
 
 }  // namespace statsd
diff --git a/statsd/tests/utils/MultiConditionTrigger_test.cpp b/statsd/tests/utils/MultiConditionTrigger_test.cpp
index 32cecd3..b525f75 100644
--- a/statsd/tests/utils/MultiConditionTrigger_test.cpp
+++ b/statsd/tests/utils/MultiConditionTrigger_test.cpp
@@ -22,6 +22,8 @@
 #include <thread>
 #include <vector>
 
+#include "tests/statsd_test_util.h"
+
 #ifdef __ANDROID__
 
 using namespace std;
@@ -166,6 +168,125 @@
     }
 }
 
+namespace {
+
+class TriggerDependency {
+public:
+    TriggerDependency(mutex& lock, condition_variable& cv, bool& triggerCalled, int& triggerCount)
+        : mLock(lock), mCv(cv), mTriggerCalled(triggerCalled), mTriggerCount(triggerCount) {
+    }
+
+    void someMethod() {
+        lock_guard lg(mLock);
+        mTriggerCount++;
+        mTriggerCalled = true;
+        mCv.notify_all();
+    }
+
+private:
+    mutex& mLock;
+    condition_variable& mCv;
+    bool& mTriggerCalled;
+    int& mTriggerCount;
+};
+
+}  // namespace
+
+TEST(MultiConditionTrigger, TestTriggerHasSleep) {
+    const string t1 = "t1";
+    set<string> conditionNames = {t1};
+
+    mutex lock;
+    condition_variable cv;
+    bool triggerCalled = false;
+    int triggerCount = 0;
+
+    {
+        TriggerDependency dependency(lock, cv, triggerCalled, triggerCount);
+        MultiConditionTrigger trigger(conditionNames, [&dependency] {
+            std::this_thread::sleep_for(std::chrono::milliseconds(50));
+            dependency.someMethod();
+        });
+        trigger.markComplete(t1);
+
+        // Here dependency instance will go out of scope and the thread within MultiConditionTrigger
+        // after delay will try to call method of already destroyed class instance
+        // with leading crash if trigger execution thread is detached in MultiConditionTrigger
+        // Instead since the MultiConditionTrigger destructor happens before TriggerDependency
+        // destructor, MultiConditionTrigger destructor is waiting on execution thread termination
+        // with thread::join
+    }
+    // At this moment the executor thread guaranteed terminated by MultiConditionTrigger destructor
+
+    // Ensure that the trigger fired.
+    {
+        unique_lock<mutex> unique_lk(lock);
+        cv.wait(unique_lk, [&triggerCalled] { return triggerCalled; });
+        EXPECT_TRUE(triggerCalled);
+        EXPECT_EQ(triggerCount, 1);
+    }
+}
+
+TEST(MultiConditionTrigger, TestTriggerHasSleepEarlyTermination) {
+    const string t1 = "t1";
+    set<string> conditionNames = {t1};
+
+    mutex lock;
+    condition_variable cv;
+    bool triggerCalled = false;
+    int triggerCount = 0;
+
+    std::condition_variable triggerTerminationFlag;
+    std::mutex triggerTerminationFlagMutex;
+    bool terminationRequested = false;
+
+    // used for error threshold tolerance due to wait_for() is involved
+    const int64_t errorThresholdMs = 25;
+    const int64_t triggerEarlyTerminationDelayMs = 100;
+    const int64_t triggerStartNs = getElapsedRealtimeNs();
+    {
+        TriggerDependency dependency(lock, cv, triggerCalled, triggerCount);
+        MultiConditionTrigger trigger(
+                conditionNames, [&dependency, &triggerTerminationFlag, &triggerTerminationFlagMutex,
+                                 &lock, &triggerCalled, &cv, &terminationRequested] {
+                    std::unique_lock<std::mutex> lk(triggerTerminationFlagMutex);
+                    if (triggerTerminationFlag.wait_for(
+                                lk, std::chrono::seconds(1),
+                                [&terminationRequested] { return terminationRequested; })) {
+                        // triggerTerminationFlag was notified - early termination is requested
+                        lock_guard lg(lock);
+                        triggerCalled = true;
+                        cv.notify_all();
+                        return;
+                    }
+                    dependency.someMethod();
+                });
+        trigger.markComplete(t1);
+
+        // notify to terminate trigger executor thread after triggerEarlyTerminationDelayMs
+        std::this_thread::sleep_for(std::chrono::milliseconds(triggerEarlyTerminationDelayMs));
+        {
+            std::unique_lock<std::mutex> lk(triggerTerminationFlagMutex);
+            terminationRequested = true;
+        }
+        triggerTerminationFlag.notify_all();
+    }
+    // At this moment the executor thread guaranteed terminated by MultiConditionTrigger destructor
+
+    // check that test duration is closer to 100ms rather to 1s
+    const int64_t triggerEndNs = getElapsedRealtimeNs();
+    EXPECT_LE(NanoToMillis(triggerEndNs - triggerStartNs),
+              triggerEarlyTerminationDelayMs + errorThresholdMs);
+
+    // Ensure that the trigger fired but not the dependency.someMethod().
+    {
+        unique_lock<mutex> unique_lk(lock);
+        cv.wait(unique_lk, [&triggerCalled] { return triggerCalled; });
+        EXPECT_TRUE(triggerCalled);
+        EXPECT_EQ(triggerCount, 0);
+    }
+}
+
 }  // namespace statsd
 }  // namespace os
 }  // namespace android
