ICU-20488 mutex static constructor fixes.

Remove the dependencies from the ICU library code on static constructors
that were introduced by using std::mutex and condition variables. The
mutexes are lazily initialized by embedding them as local static variables
in getter functions, and relying on the C++ compiler/runtime to do thread
safe initialization of them.
diff --git a/icu4c/source/common/brkeng.cpp b/icu4c/source/common/brkeng.cpp
index 7144af6..19467dc 100644
--- a/icu4c/source/common/brkeng.cpp
+++ b/icu4c/source/common/brkeng.cpp
@@ -124,13 +124,12 @@
 U_CDECL_END
 U_NAMESPACE_BEGIN
 
-static UMutex gBreakEngineMutex = U_MUTEX_INITIALIZER;
-
 const LanguageBreakEngine *
 ICULanguageBreakFactory::getEngineFor(UChar32 c) {
     const LanguageBreakEngine *lbe = NULL;
     UErrorCode  status = U_ZERO_ERROR;
 
+    static UMutex gBreakEngineMutex = U_MUTEX_INITIALIZER;
     Mutex m(&gBreakEngineMutex);
 
     if (fEngines == NULL) {
diff --git a/icu4c/source/common/characterproperties.cpp b/icu4c/source/common/characterproperties.cpp
index 96186e6..5a57364 100644
--- a/icu4c/source/common/characterproperties.cpp
+++ b/icu4c/source/common/characterproperties.cpp
@@ -47,7 +47,10 @@
 
 UCPMap *maps[UCHAR_INT_LIMIT - UCHAR_INT_START] = {};
 
-icu::UMutex cpMutex = U_MUTEX_INITIALIZER;
+icu::UMutex *cpMutex() {
+    static icu::UMutex m = U_MUTEX_INITIALIZER;
+    return &m;
+}
 
 //----------------------------------------------------------------
 // Inclusions list
@@ -358,7 +361,7 @@
         *pErrorCode = U_ILLEGAL_ARGUMENT_ERROR;
         return nullptr;
     }
-    Mutex m(&cpMutex);
+    Mutex m(cpMutex());
     UnicodeSet *set = sets[property];
     if (set == nullptr) {
         sets[property] = set = makeSet(property, *pErrorCode);
@@ -374,7 +377,7 @@
         *pErrorCode = U_ILLEGAL_ARGUMENT_ERROR;
         return nullptr;
     }
-    Mutex m(&cpMutex);
+    Mutex m(cpMutex());
     UCPMap *map = maps[property - UCHAR_INT_START];
     if (map == nullptr) {
         maps[property - UCHAR_INT_START] = map = makeMap(property, *pErrorCode);
diff --git a/icu4c/source/common/locdspnm.cpp b/icu4c/source/common/locdspnm.cpp
index 2d9389e..da35be9 100644
--- a/icu4c/source/common/locdspnm.cpp
+++ b/icu4c/source/common/locdspnm.cpp
@@ -286,7 +286,6 @@
 #else
     UObject* capitalizationBrkIter;
 #endif
-    static UMutex  capitalizationBrkIterLock;
     UnicodeString formatOpenParen;
     UnicodeString formatReplaceOpenParen;
     UnicodeString formatCloseParen;
@@ -352,8 +351,6 @@
     struct CapitalizationContextSink;
 };
 
-UMutex LocaleDisplayNamesImpl::capitalizationBrkIterLock = U_MUTEX_INITIALIZER;
-
 LocaleDisplayNamesImpl::LocaleDisplayNamesImpl(const Locale& locale,
                                                UDialectHandling dialectHandling)
     : dialectHandling(dialectHandling)
@@ -552,6 +549,7 @@
     if ( result.length() > 0 && u_islower(result.char32At(0)) && capitalizationBrkIter!= NULL &&
           ( capitalizationContext==UDISPCTX_CAPITALIZATION_FOR_BEGINNING_OF_SENTENCE || fCapitalization[usage] ) ) {
         // note fCapitalization[usage] won't be set unless capitalizationContext is UI_LIST_OR_MENU or STANDALONE
+        static UMutex capitalizationBrkIterLock = U_MUTEX_INITIALIZER;
         Mutex lock(&capitalizationBrkIterLock);
         result.toTitle(capitalizationBrkIter, locale, U_TITLECASE_NO_LOWERCASE | U_TITLECASE_NO_BREAK_ADJUSTMENT);
     }
diff --git a/icu4c/source/common/locid.cpp b/icu4c/source/common/locid.cpp
index a6a5182..06986b6 100644
--- a/icu4c/source/common/locid.cpp
+++ b/icu4c/source/common/locid.cpp
@@ -62,7 +62,10 @@
 static UInitOnce gLocaleCacheInitOnce = U_INITONCE_INITIALIZER;
 
 // gDefaultLocaleMutex protects all access to gDefaultLocalesHashT and gDefaultLocale.
-static UMutex gDefaultLocaleMutex = U_MUTEX_INITIALIZER;
+static UMutex *gDefaultLocaleMutex() {
+    static UMutex m = U_MUTEX_INITIALIZER;
+    return &m;
+}
 static UHashtable *gDefaultLocalesHashT = NULL;
 static Locale *gDefaultLocale = NULL;
 
@@ -171,7 +174,7 @@
 
 Locale *locale_set_default_internal(const char *id, UErrorCode& status) {
     // Synchronize this entire function.
-    Mutex lock(&gDefaultLocaleMutex);
+    Mutex lock(gDefaultLocaleMutex());
 
     UBool canonicalize = FALSE;
 
@@ -708,7 +711,7 @@
 Locale::getDefault()
 {
     {
-        Mutex lock(&gDefaultLocaleMutex);
+        Mutex lock(gDefaultLocaleMutex());
         if (gDefaultLocale != NULL) {
             return *gDefaultLocale;
         }
diff --git a/icu4c/source/common/putil.cpp b/icu4c/source/common/putil.cpp
index 9ed85c0..42db744 100644
--- a/icu4c/source/common/putil.cpp
+++ b/icu4c/source/common/putil.cpp
@@ -241,7 +241,6 @@
 UDate fakeClock_t0 = 0; /** Time to start the clock from **/
 UDate fakeClock_dt = 0; /** Offset (fake time - real time) **/
 UBool fakeClock_set = FALSE; /** True if fake clock has spun up **/
-static UMutex fakeClockMutex = U_MUTEX_INTIALIZER;
 
 static UDate getUTCtime_real() {
     struct timeval posixTime;
@@ -250,6 +249,7 @@
 }
 
 static UDate getUTCtime_fake() {
+    static UMutex fakeClockMutex = U_MUTEX_INTIALIZER;
     umtx_lock(&fakeClockMutex);
     if(!fakeClock_set) {
         UDate real = getUTCtime_real();
diff --git a/icu4c/source/common/resbund.cpp b/icu4c/source/common/resbund.cpp
index 512bd53..08cda3a 100644
--- a/icu4c/source/common/resbund.cpp
+++ b/icu4c/source/common/resbund.cpp
@@ -376,8 +376,8 @@
     ures_getVersion(fResource, versionInfo);
 }
 
-static UMutex gLocaleLock = U_MUTEX_INITIALIZER;
 const Locale &ResourceBundle::getLocale(void) const {
+    static UMutex gLocaleLock = U_MUTEX_INITIALIZER;
     Mutex lock(&gLocaleLock);
     if (fLocale != NULL) {
         return *fLocale;
diff --git a/icu4c/source/common/serv.cpp b/icu4c/source/common/serv.cpp
index 619e8c7..555c055 100644
--- a/icu4c/source/common/serv.cpp
+++ b/icu4c/source/common/serv.cpp
@@ -333,7 +333,10 @@
 ******************************************************************
 */
 
-static UMutex lock = U_MUTEX_INITIALIZER;
+static UMutex *lock() {
+    static UMutex m = U_MUTEX_INITIALIZER;
+    return &m;
+}
 
 ICUService::ICUService()
 : name()
@@ -358,7 +361,7 @@
 ICUService::~ICUService()
 {
     {
-        Mutex mutex(&lock);
+        Mutex mutex(lock());
         clearCaches();
         delete factories;
         factories = NULL;
@@ -449,7 +452,7 @@
         // if factory is not null, we're calling from within the mutex,
         // and since some unix machines don't have reentrant mutexes we
         // need to make sure not to try to lock it again.
-        XMutex mutex(&lock, factory != NULL);
+        XMutex mutex(lock(), factory != NULL);
 
         if (serviceCache == NULL) {
             ncthis->serviceCache = new Hashtable(status);
@@ -615,7 +618,7 @@
     }
 
     {
-        Mutex mutex(&lock);
+        Mutex mutex(lock());
         const Hashtable* map = getVisibleIDMap(status);
         if (map != NULL) {
             ICUServiceKey* fallbackKey = createKey(matchID, status);
@@ -692,7 +695,7 @@
 {
     {
         UErrorCode status = U_ZERO_ERROR;
-        Mutex mutex(&lock);
+        Mutex mutex(lock());
         const Hashtable* map = getVisibleIDMap(status);
         if (map != NULL) {
             ICUServiceFactory* f = (ICUServiceFactory*)map->get(id);
@@ -744,7 +747,7 @@
     result.setDeleter(userv_deleteStringPair);
     if (U_SUCCESS(status)) {
         ICUService* ncthis = (ICUService*)this; // cast away semantic const
-        Mutex mutex(&lock);
+        Mutex mutex(lock());
 
         if (dnCache != NULL && dnCache->locale != locale) {
             delete dnCache;
@@ -849,7 +852,7 @@
 ICUService::registerFactory(ICUServiceFactory* factoryToAdopt, UErrorCode& status) 
 {
     if (U_SUCCESS(status) && factoryToAdopt != NULL) {
-        Mutex mutex(&lock);
+        Mutex mutex(lock());
 
         if (factories == NULL) {
             factories = new UVector(deleteUObject, NULL, status);
@@ -880,7 +883,7 @@
     ICUServiceFactory *factory = (ICUServiceFactory*)rkey;
     UBool result = FALSE;
     if (factory != NULL && factories != NULL) {
-        Mutex mutex(&lock);
+        Mutex mutex(lock());
 
         if (factories->removeElement(factory)) {
             clearCaches();
@@ -900,7 +903,7 @@
 ICUService::reset() 
 {
     {
-        Mutex mutex(&lock);
+        Mutex mutex(lock());
         reInitializeFactories();
         clearCaches();
     }
diff --git a/icu4c/source/common/servls.cpp b/icu4c/source/common/servls.cpp
index f4579d0..90874d1 100644
--- a/icu4c/source/common/servls.cpp
+++ b/icu4c/source/common/servls.cpp
@@ -26,7 +26,6 @@
 
 U_NAMESPACE_BEGIN
 
-static UMutex llock = U_MUTEX_INITIALIZER;
 ICULocaleService::ICULocaleService()
   : fallbackLocale(Locale::getDefault())
 {
@@ -264,6 +263,7 @@
 {
     const Locale&     loc    = Locale::getDefault();
     ICULocaleService* ncThis = (ICULocaleService*)this;
+    static UMutex llock = U_MUTEX_INITIALIZER;
     {
         Mutex mutex(&llock);
         if (loc != fallbackLocale) {
diff --git a/icu4c/source/common/servnotf.cpp b/icu4c/source/common/servnotf.cpp
index dc77c7b..1e65a14 100644
--- a/icu4c/source/common/servnotf.cpp
+++ b/icu4c/source/common/servnotf.cpp
@@ -21,7 +21,10 @@
 EventListener::~EventListener() {}
 UOBJECT_DEFINE_RTTI_IMPLEMENTATION(EventListener)
 
-static UMutex notifyLock = U_MUTEX_INITIALIZER;
+static UMutex *notifyLock() {
+    static UMutex m = U_MUTEX_INITIALIZER;
+    return &m;
+}
 
 ICUNotifier::ICUNotifier(void) 
 : listeners(NULL) 
@@ -30,7 +33,7 @@
 
 ICUNotifier::~ICUNotifier(void) {
     {
-        Mutex lmx(&notifyLock);
+        Mutex lmx(notifyLock());
         delete listeners;
         listeners = NULL;
     }
@@ -47,7 +50,7 @@
         }
 
         if (acceptsListener(*l)) {
-            Mutex lmx(&notifyLock);
+            Mutex lmx(notifyLock());
             if (listeners == NULL) {
                 listeners = new UVector(5, status);
             } else {
@@ -80,7 +83,7 @@
         }
 
         {
-            Mutex lmx(&notifyLock);
+            Mutex lmx(notifyLock());
             if (listeners != NULL) {
                 // identity equality check
                 for (int i = 0, e = listeners->size(); i < e; ++i) {
@@ -103,7 +106,7 @@
 ICUNotifier::notifyChanged(void) 
 {
     if (listeners != NULL) {
-        Mutex lmx(&notifyLock);
+        Mutex lmx(notifyLock());
         if (listeners != NULL) {
             for (int i = 0, e = listeners->size(); i < e; ++i) {
                 EventListener* el = (EventListener*)listeners->elementAt(i);
diff --git a/icu4c/source/common/ucnv_bld.cpp b/icu4c/source/common/ucnv_bld.cpp
index 18e46e1..b71be8f 100644
--- a/icu4c/source/common/ucnv_bld.cpp
+++ b/icu4c/source/common/ucnv_bld.cpp
@@ -194,9 +194,12 @@
 
 /*initializes some global variables */
 static UHashtable *SHARED_DATA_HASHTABLE = NULL;
-static icu::UMutex cnvCacheMutex = U_MUTEX_INITIALIZER;  /* Mutex for synchronizing cnv cache access. */
-                                                         /*  Note:  the global mutex is used for      */
-                                                         /*         reference count updates.          */
+static icu::UMutex *cnvCacheMutex() {                 /* Mutex for synchronizing cnv cache access. */
+    static icu::UMutex m = U_MUTEX_INITIALIZER;
+    return &m;
+}
+/*  Note:  the global mutex is used for      */
+/*         reference count updates.          */
 
 static const char **gAvailableConverters = NULL;
 static uint16_t gAvailableConverterCount = 0;
@@ -599,9 +602,9 @@
 ucnv_unloadSharedDataIfReady(UConverterSharedData *sharedData)
 {
     if(sharedData != NULL && sharedData->isReferenceCounted) {
-        umtx_lock(&cnvCacheMutex);
+        umtx_lock(cnvCacheMutex());
         ucnv_unload(sharedData);
-        umtx_unlock(&cnvCacheMutex);
+        umtx_unlock(cnvCacheMutex());
     }
 }
 
@@ -609,9 +612,9 @@
 ucnv_incrementRefCount(UConverterSharedData *sharedData)
 {
     if(sharedData != NULL && sharedData->isReferenceCounted) {
-        umtx_lock(&cnvCacheMutex);
+        umtx_lock(cnvCacheMutex());
         sharedData->referenceCounter++;
-        umtx_unlock(&cnvCacheMutex);
+        umtx_unlock(cnvCacheMutex());
     }
 }
 
@@ -812,9 +815,9 @@
         pArgs->nestedLoads=1;
         pArgs->pkg=NULL;
 
-        umtx_lock(&cnvCacheMutex);
+        umtx_lock(cnvCacheMutex());
         mySharedConverterData = ucnv_load(pArgs, err);
-        umtx_unlock(&cnvCacheMutex);
+        umtx_unlock(cnvCacheMutex());
         if (U_FAILURE (*err) || (mySharedConverterData == NULL))
         {
             return NULL;
@@ -1061,7 +1064,7 @@
     *                   because the sequence of looking up in the cache + incrementing
     *                   is protected by cnvCacheMutex.
     */
-    umtx_lock(&cnvCacheMutex);
+    umtx_lock(cnvCacheMutex());
     /*
      * double loop: A delta/extension-only converter has a pointer to its base table's
      * shared data; the first iteration of the outer loop may see the delta converter
@@ -1090,7 +1093,7 @@
             }
         }
     } while(++i == 1 && remaining > 0);
-    umtx_unlock(&cnvCacheMutex);
+    umtx_unlock(cnvCacheMutex());
 
     UTRACE_DATA1(UTRACE_INFO, "ucnv_flushCache() exits with %d converters remaining", remaining);
 
@@ -1196,7 +1199,7 @@
     }
     algorithmicSharedData = getAlgorithmicTypeFromName(stackArgs.name);
 
-    umtx_lock(&cnvCacheMutex);
+    umtx_lock(cnvCacheMutex());
 
     gDefaultAlgorithmicSharedData = algorithmicSharedData;
     gDefaultConverterContainsOption = containsOption;
@@ -1212,7 +1215,7 @@
 
     ucnv_enableCleanup();
 
-    umtx_unlock(&cnvCacheMutex);
+    umtx_unlock(cnvCacheMutex());
 }
 #endif
 
@@ -1237,7 +1240,7 @@
     but ucnv_setDefaultName is not thread safe.
     */
     {
-        icu::Mutex lock(&cnvCacheMutex);
+        icu::Mutex lock(cnvCacheMutex());
         name = gDefaultConverterName;
     }
     if(name==NULL) {
diff --git a/icu4c/source/common/ucurr.cpp b/icu4c/source/common/ucurr.cpp
index 802eafb..444adc0 100644
--- a/icu4c/source/common/ucurr.cpp
+++ b/icu4c/source/common/ucurr.cpp
@@ -365,7 +365,10 @@
 #if !UCONFIG_NO_SERVICE
 struct CReg;
 
-static UMutex gCRegLock = U_MUTEX_INITIALIZER;
+static UMutex *gCRegLock() {
+    static UMutex m = U_MUTEX_INITIALIZER;
+    return &m;
+}
 static CReg* gCRegHead = 0;
 
 struct CReg : public icu::UMemory {
@@ -391,14 +394,14 @@
         if (status && U_SUCCESS(*status) && _iso && _id) {
             CReg* n = new CReg(_iso, _id);
             if (n) {
-                umtx_lock(&gCRegLock);
+                umtx_lock(gCRegLock());
                 if (!gCRegHead) {
                     /* register for the first time */
                     ucln_common_registerCleanup(UCLN_COMMON_CURRENCY, currency_cleanup);
                 }
                 n->next = gCRegHead;
                 gCRegHead = n;
-                umtx_unlock(&gCRegLock);
+                umtx_unlock(gCRegLock());
                 return n;
             }
             *status = U_MEMORY_ALLOCATION_ERROR;
@@ -408,7 +411,7 @@
 
     static UBool unreg(UCurrRegistryKey key) {
         UBool found = FALSE;
-        umtx_lock(&gCRegLock);
+        umtx_lock(gCRegLock());
 
         CReg** p = &gCRegHead;
         while (*p) {
@@ -421,13 +424,13 @@
             p = &((*p)->next);
         }
 
-        umtx_unlock(&gCRegLock);
+        umtx_unlock(gCRegLock());
         return found;
     }
 
     static const UChar* get(const char* id) {
         const UChar* result = NULL;
-        umtx_lock(&gCRegLock);
+        umtx_lock(gCRegLock());
         CReg* p = gCRegHead;
 
         /* register cleanup of the mutex */
@@ -439,7 +442,7 @@
             }
             p = p->next;
         }
-        umtx_unlock(&gCRegLock);
+        umtx_unlock(gCRegLock());
         return result;
     }
 
@@ -1353,7 +1356,10 @@
 // It is a simple round-robin replacement strategy.
 static int8_t currentCacheEntryIndex = 0;
 
-static UMutex gCurrencyCacheMutex = U_MUTEX_INITIALIZER;
+static UMutex *gCurrencyCacheMutex() {
+    static UMutex m = U_MUTEX_INITIALIZER;
+    return &m;
+}
 
 // Cache deletion
 static void
@@ -1402,7 +1408,7 @@
     CurrencyNameStruct* currencySymbols = NULL;
     CurrencyNameCacheEntry* cacheEntry = NULL;
 
-    umtx_lock(&gCurrencyCacheMutex);
+    umtx_lock(gCurrencyCacheMutex());
     // in order to handle racing correctly,
     // not putting 'search' in a separate function.
     int8_t found = -1;
@@ -1417,13 +1423,13 @@
         cacheEntry = currCache[found];
         ++(cacheEntry->refCount);
     }
-    umtx_unlock(&gCurrencyCacheMutex);
+    umtx_unlock(gCurrencyCacheMutex());
     if (found == -1) {
         collectCurrencyNames(locale, &currencyNames, &total_currency_name_count, &currencySymbols, &total_currency_symbol_count, ec);
         if (U_FAILURE(ec)) {
             return NULL;
         }
-        umtx_lock(&gCurrencyCacheMutex);
+        umtx_lock(gCurrencyCacheMutex());
         // check again.
         for (int8_t i = 0; i < CURRENCY_NAME_CACHE_NUM; ++i) {
             if (currCache[i]!= NULL &&
@@ -1462,19 +1468,19 @@
             cacheEntry = currCache[found];
             ++(cacheEntry->refCount);
         }
-        umtx_unlock(&gCurrencyCacheMutex);
+        umtx_unlock(gCurrencyCacheMutex());
     }
 
     return cacheEntry;
 }
 
 static void releaseCacheEntry(CurrencyNameCacheEntry* cacheEntry) {
-    umtx_lock(&gCurrencyCacheMutex);
+    umtx_lock(gCurrencyCacheMutex());
     --(cacheEntry->refCount);
     if (cacheEntry->refCount == 0) {  // remove
         deleteCacheEntry(cacheEntry);
     }
-    umtx_unlock(&gCurrencyCacheMutex);
+    umtx_unlock(gCurrencyCacheMutex());
 }
 
 U_CAPI void
diff --git a/icu4c/source/common/umutex.cpp b/icu4c/source/common/umutex.cpp
index 7873314..20b03d6 100644
--- a/icu4c/source/common/umutex.cpp
+++ b/icu4c/source/common/umutex.cpp
@@ -42,12 +42,15 @@
  *************************************************************************************************/
 
 // The ICU global mutex. Used when ICU implementation code passes NULL for the mutex pointer.
-static UMutex   globalMutex = U_MUTEX_INITIALIZER;
+static UMutex *globalMutex() {
+    static UMutex m = U_MUTEX_INITIALIZER;
+    return &m;
+}
 
 U_CAPI void  U_EXPORT2
 umtx_lock(UMutex *mutex) {
     if (mutex == nullptr) {
-        mutex = &globalMutex;
+        mutex = globalMutex();
     }
     mutex->fMutex.lock();
 }
@@ -57,7 +60,7 @@
 umtx_unlock(UMutex* mutex)
 {
     if (mutex == nullptr) {
-        mutex = &globalMutex;
+        mutex = globalMutex();
     }
     mutex->fMutex.unlock();
 }
@@ -71,7 +74,7 @@
 U_CAPI void U_EXPORT2
 umtx_condWait(UConditionVar *cond, UMutex *mutex) {
     if (mutex == nullptr) {
-        mutex = &globalMutex;
+        mutex = globalMutex();
     }
     cond->fCV.wait(mutex->fMutex);
 }
@@ -95,8 +98,15 @@
  *
  *************************************************************************************************/
 
-static std::mutex initMutex;
-static std::condition_variable initCondition;
+static std::mutex &initMutex() {
+    static std::mutex m;
+    return m;
+}
+
+static std::condition_variable &initCondition() {
+    static std::condition_variable cv;
+    return cv;
+}
 
 
 // This function is called when a test of a UInitOnce::fState reveals that
@@ -109,7 +119,7 @@
 //
 U_COMMON_API UBool U_EXPORT2
 umtx_initImplPreInit(UInitOnce &uio) {
-    std::unique_lock<std::mutex> lock(initMutex);
+    std::unique_lock<std::mutex> lock(initMutex());
 
     if (umtx_loadAcquire(uio.fState) == 0) {
         umtx_storeRelease(uio.fState, 1);
@@ -118,7 +128,7 @@
         while (umtx_loadAcquire(uio.fState) == 1) {
             // Another thread is currently running the initialization.
             // Wait until it completes.
-            initCondition.wait(lock);
+            initCondition().wait(lock);
         }
         U_ASSERT(uio.fState == 2);
         return false;
@@ -135,10 +145,10 @@
 U_COMMON_API void U_EXPORT2
 umtx_initImplPostInit(UInitOnce &uio) {
     {
-        std::unique_lock<std::mutex> lock(initMutex);
+        std::unique_lock<std::mutex> lock(initMutex());
         umtx_storeRelease(uio.fState, 2);
     }
-    initCondition.notify_all();
+    initCondition().notify_all();
 }
 
 U_NAMESPACE_END
diff --git a/icu4c/source/common/unifiedcache.cpp b/icu4c/source/common/unifiedcache.cpp
index 6ad8c3d..641f4ec 100644
--- a/icu4c/source/common/unifiedcache.cpp
+++ b/icu4c/source/common/unifiedcache.cpp
@@ -21,8 +21,14 @@
 #include "umutex.h"
 
 static icu::UnifiedCache *gCache = NULL;
-static icu::UMutex gCacheMutex = U_MUTEX_INITIALIZER;
-static icu::UConditionVar gInProgressValueAddedCond = U_CONDITION_INITIALIZER;
+static icu::UMutex *gCacheMutex() {
+    static icu::UMutex m = U_MUTEX_INITIALIZER;
+    return &m;
+}
+static icu::UConditionVar *gInProgressValueAddedCond() {
+    static icu::UConditionVar cv = U_CONDITION_INITIALIZER;
+    return &cv;
+}
 static icu::UInitOnce gCacheInitOnce = U_INITONCE_INITIALIZER;
 
 static const int32_t MAX_EVICT_ITERATIONS = 10;
@@ -132,28 +138,28 @@
         status = U_ILLEGAL_ARGUMENT_ERROR;
         return;
     }
-    Mutex lock(&gCacheMutex);
+    Mutex lock(gCacheMutex());
     fMaxUnused = count;
     fMaxPercentageOfInUse = percentageOfInUseItems;
 }
 
 int32_t UnifiedCache::unusedCount() const {
-    Mutex lock(&gCacheMutex);
+    Mutex lock(gCacheMutex());
     return uhash_count(fHashtable) - fNumValuesInUse;
 }
 
 int64_t UnifiedCache::autoEvictedCount() const {
-    Mutex lock(&gCacheMutex);
+    Mutex lock(gCacheMutex());
     return fAutoEvictedCount;
 }
 
 int32_t UnifiedCache::keyCount() const {
-    Mutex lock(&gCacheMutex);
+    Mutex lock(gCacheMutex());
     return uhash_count(fHashtable);
 }
 
 void UnifiedCache::flush() const {
-    Mutex lock(&gCacheMutex);
+    Mutex lock(gCacheMutex());
 
     // Use a loop in case cache items that are flushed held hard references to
     // other cache items making those additional cache items eligible for
@@ -162,7 +168,7 @@
 }
 
 void UnifiedCache::handleUnreferencedObject() const {
-    Mutex lock(&gCacheMutex);
+    Mutex lock(gCacheMutex());
     --fNumValuesInUse;
     _runEvictionSlice();
 }
@@ -181,7 +187,7 @@
 }
 
 void UnifiedCache::dumpContents() const {
-    Mutex lock(&gCacheMutex);
+    Mutex lock(gCacheMutex());
     _dumpContents();
 }
 
@@ -221,7 +227,7 @@
         // Now all that should be left in the cache are entries that refer to
         // each other and entries with hard references from outside the cache.
         // Nothing we can do about these so proceed to wipe out the cache.
-        Mutex lock(&gCacheMutex);
+        Mutex lock(gCacheMutex());
         _flush(TRUE);
     }
     uhash_close(fHashtable);
@@ -322,7 +328,7 @@
         const CacheKeyBase &key,
         const SharedObject *&value,
         UErrorCode &status) const {
-    Mutex lock(&gCacheMutex);
+    Mutex lock(gCacheMutex());
     const UHashElement *element = uhash_find(fHashtable, &key);
     if (element != NULL && !_inProgress(element)) {
         _fetch(element, value, status);
@@ -347,14 +353,14 @@
         UErrorCode &status) const {
     U_ASSERT(value == NULL);
     U_ASSERT(status == U_ZERO_ERROR);
-    Mutex lock(&gCacheMutex);
+    Mutex lock(gCacheMutex());
     const UHashElement *element = uhash_find(fHashtable, &key);
 
     // If the hash table contains an inProgress placeholder entry for this key,
     // this means that another thread is currently constructing the value object.
     // Loop, waiting for that construction to complete.
      while (element != NULL && _inProgress(element)) {
-        umtx_condWait(&gInProgressValueAddedCond, &gCacheMutex);
+        umtx_condWait(gInProgressValueAddedCond(), gCacheMutex());
         element = uhash_find(fHashtable, &key);
     }
 
@@ -427,7 +433,7 @@
 
     // Tell waiting threads that we replace in-progress status with
     // an error.
-    umtx_condBroadcast(&gInProgressValueAddedCond);
+    umtx_condBroadcast(gInProgressValueAddedCond());
 }
 
 void UnifiedCache::_fetch(
diff --git a/icu4c/source/common/uresbund.cpp b/icu4c/source/common/uresbund.cpp
index 45bb92b..af6d1a1 100644
--- a/icu4c/source/common/uresbund.cpp
+++ b/icu4c/source/common/uresbund.cpp
@@ -49,7 +49,10 @@
 static UHashtable *cache = NULL;
 static icu::UInitOnce gCacheInitOnce;
 
-static UMutex resbMutex = U_MUTEX_INITIALIZER;
+static UMutex *resbMutex() {
+    static UMutex m = U_MUTEX_INITIALIZER;
+    return &m;
+}
 
 /* INTERNAL: hashes an entry  */
 static int32_t U_CALLCONV hashEntry(const UHashTok parm) {
@@ -93,13 +96,13 @@
  *  Internal function
  */
 static void entryIncrease(UResourceDataEntry *entry) {
-    umtx_lock(&resbMutex);
+    umtx_lock(resbMutex());
     entry->fCountExisting++;
     while(entry->fParent != NULL) {
       entry = entry->fParent;
       entry->fCountExisting++;
     }
-    umtx_unlock(&resbMutex);
+    umtx_unlock(resbMutex());
 }
 
 /**
@@ -181,9 +184,9 @@
     /*if shared data hasn't even been lazy evaluated yet
     * return 0
     */
-    umtx_lock(&resbMutex);
+    umtx_lock(resbMutex());
     if (cache == NULL) {
-        umtx_unlock(&resbMutex);
+        umtx_unlock(resbMutex());
         return 0;
     }
 
@@ -215,7 +218,7 @@
          * got decremented by free_entry().
          */
     } while(deletedMore);
-    umtx_unlock(&resbMutex);
+    umtx_unlock(resbMutex());
 
     return rbDeletedNum;
 }
@@ -229,9 +232,9 @@
   const UHashElement *e;
   UResourceDataEntry *resB;
   
-    umtx_lock(&resbMutex);
+    umtx_lock(resbMutex());
     if (cache == NULL) {
-      umtx_unlock(&resbMutex);
+      umtx_unlock(resbMutex());
       fprintf(stderr,"%s:%d: RB Cache is NULL.\n", __FILE__, __LINE__);
       return FALSE;
     }
@@ -251,7 +254,7 @@
     
     fprintf(stderr,"%s:%d: RB Cache still contains %d items.\n", __FILE__, __LINE__, uhash_count(cache));
 
-    umtx_unlock(&resbMutex);
+    umtx_unlock(resbMutex());
     
     return cacheNotEmpty;
 }
@@ -663,7 +666,7 @@
         }
     }
  
-    umtx_lock(&resbMutex);
+    umtx_lock(resbMutex());
     { /* umtx_lock */
         /* We're going to skip all the locales that do not have any data */
         r = findFirstExisting(path, name, &isRoot, &hasChopped, &isDefault, &intStatus);
@@ -762,7 +765,7 @@
         }
     } /* umtx_lock */
 finishUnlock:
-    umtx_unlock(&resbMutex);
+    umtx_unlock(resbMutex());
 
     if(U_SUCCESS(*status)) {
         if(intStatus != U_ZERO_ERROR) {
@@ -787,7 +790,7 @@
         return NULL;
     }
 
-    umtx_lock(&resbMutex);
+    umtx_lock(resbMutex());
     // findFirstExisting() without fallbacks.
     UResourceDataEntry *r = init_entry(localeID, path, status);
     if(U_SUCCESS(*status)) {
@@ -825,7 +828,7 @@
             t1 = t1->fParent;
         }
     }
-    umtx_unlock(&resbMutex);
+    umtx_unlock(resbMutex());
     return r;
 }
 
@@ -868,9 +871,9 @@
  */
 
 static void entryClose(UResourceDataEntry *resB) {
-  umtx_lock(&resbMutex);
+  umtx_lock(resbMutex());
   entryCloseInt(resB);
-  umtx_unlock(&resbMutex);
+  umtx_unlock(resbMutex());
 }
 
 /*
diff --git a/icu4c/source/common/usprep.cpp b/icu4c/source/common/usprep.cpp
index 01238b3..a05fae1 100644
--- a/icu4c/source/common/usprep.cpp
+++ b/icu4c/source/common/usprep.cpp
@@ -47,7 +47,10 @@
 static UHashtable *SHARED_DATA_HASHTABLE = NULL;
 static icu::UInitOnce gSharedDataInitOnce;
 
-static UMutex usprepMutex = U_MUTEX_INITIALIZER;
+static UMutex *usprepMutex() {
+    static UMutex m = U_MUTEX_INITIALIZER;
+    return &m;
+}
 
 /* format version of spp file */
 //static uint8_t formatVersion[4]={ 0, 0, 0, 0 };
@@ -148,9 +151,9 @@
      * if shared data hasn't even been lazy evaluated yet
      * return 0
      */
-    umtx_lock(&usprepMutex);
+    umtx_lock(usprepMutex());
     if (SHARED_DATA_HASHTABLE == NULL) {
-        umtx_unlock(&usprepMutex);
+        umtx_unlock(usprepMutex());
         return 0;
     }
 
@@ -181,7 +184,7 @@
         }
        
     }
-    umtx_unlock(&usprepMutex);
+    umtx_unlock(usprepMutex());
 
     return deletedNum;
 }
@@ -259,7 +262,7 @@
     }
 
     /* in the mutex block, set the data for this process */
-    umtx_lock(&usprepMutex);
+    umtx_lock(usprepMutex());
     if(profile->sprepData==NULL) {
         profile->sprepData=dataMemory;
         dataMemory=NULL;
@@ -268,7 +271,7 @@
     } else {
         p=(const int32_t *)udata_getMemory(profile->sprepData);
     }
-    umtx_unlock(&usprepMutex);
+    umtx_unlock(usprepMutex());
     /* initialize some variables */
     profile->mappingData=(uint16_t *)((uint8_t *)(p+_SPREP_INDEX_TOP)+profile->indexes[_SPREP_INDEX_TRIE_SIZE]);
     
@@ -325,12 +328,12 @@
     stackKey.path = (char*) path;
 
     /* fetch the data from the cache */
-    umtx_lock(&usprepMutex);
+    umtx_lock(usprepMutex());
     profile = (UStringPrepProfile*) (uhash_get(SHARED_DATA_HASHTABLE,&stackKey));
     if(profile != NULL) {
         profile->refCount++;
     }
-    umtx_unlock(&usprepMutex);
+    umtx_unlock(usprepMutex());
     
     if(profile == NULL) {
         /* else load the data and put the data in the cache */
@@ -362,7 +365,7 @@
             return NULL;
         }
 
-        umtx_lock(&usprepMutex);
+        umtx_lock(usprepMutex());
         // If another thread already inserted the same key/value, refcount and cleanup our thread data
         profile = (UStringPrepProfile*) (uhash_get(SHARED_DATA_HASHTABLE,&stackKey));
         if(profile != NULL) {
@@ -383,7 +386,7 @@
             profile->refCount = 1;
             uhash_put(SHARED_DATA_HASHTABLE, key.orphan(), profile, status);
         }
-        umtx_unlock(&usprepMutex);
+        umtx_unlock(usprepMutex());
     }
 
     return profile;
@@ -422,12 +425,12 @@
         return;
     }
 
-    umtx_lock(&usprepMutex);
+    umtx_lock(usprepMutex());
     /* decrement the ref count*/
     if(profile->refCount > 0){
         profile->refCount--;
     }
-    umtx_unlock(&usprepMutex);
+    umtx_unlock(usprepMutex());
     
 }
 
diff --git a/icu4c/source/i18n/astro.cpp b/icu4c/source/i18n/astro.cpp
index bb37016..e6dcfe8 100644
--- a/icu4c/source/i18n/astro.cpp
+++ b/icu4c/source/i18n/astro.cpp
@@ -65,7 +65,10 @@
   return(uprv_isNaN(d));
 }
 
-static icu::UMutex ccLock = U_MUTEX_INITIALIZER;
+static icu::UMutex *ccLock() {
+    static icu::UMutex m = U_MUTEX_INITIALIZER;
+    return &m;
+}
 
 U_CDECL_BEGIN
 static UBool calendar_astro_cleanup(void) {
@@ -1549,12 +1552,12 @@
     if(U_FAILURE(status)) {
         return 0;
     }
-    umtx_lock(&ccLock);
+    umtx_lock(ccLock());
 
     if(*cache == NULL) {
         createCache(cache, status);
         if(U_FAILURE(status)) {
-            umtx_unlock(&ccLock);
+            umtx_unlock(ccLock());
             return 0;
         }
     }
@@ -1562,7 +1565,7 @@
     res = uhash_igeti((*cache)->fTable, key);
     U_DEBUG_ASTRO_MSG(("%p: GET: [%d] == %d\n", (*cache)->fTable, key, res));
 
-    umtx_unlock(&ccLock);
+    umtx_unlock(ccLock());
     return res;
 }
 
@@ -1570,12 +1573,12 @@
     if(U_FAILURE(status)) {
         return;
     }
-    umtx_lock(&ccLock);
+    umtx_lock(ccLock());
 
     if(*cache == NULL) {
         createCache(cache, status);
         if(U_FAILURE(status)) {
-            umtx_unlock(&ccLock);
+            umtx_unlock(ccLock());
             return;
         }
     }
@@ -1583,7 +1586,7 @@
     uhash_iputi((*cache)->fTable, key, value, &status);
     U_DEBUG_ASTRO_MSG(("%p: PUT: [%d] := %d\n", (*cache)->fTable, key, value));
 
-    umtx_unlock(&ccLock);
+    umtx_unlock(ccLock());
 }
 
 CalendarCache::CalendarCache(int32_t size, UErrorCode &status) {
diff --git a/icu4c/source/i18n/chnsecal.cpp b/icu4c/source/i18n/chnsecal.cpp
index 69c9040..2472870 100644
--- a/icu4c/source/i18n/chnsecal.cpp
+++ b/icu4c/source/i18n/chnsecal.cpp
@@ -51,7 +51,10 @@
 
 
 // --- The cache --
-static icu::UMutex astroLock = U_MUTEX_INITIALIZER;  // Protects access to gChineseCalendarAstro.
+static icu::UMutex *astroLock() {  // Protects access to gChineseCalendarAstro.
+    static icu::UMutex m = U_MUTEX_INITIALIZER;
+    return &m;
+}
 static icu::CalendarAstronomer *gChineseCalendarAstro = NULL;
 
 // Lazy Creation & Access synchronized by class CalendarCache with a mutex.
@@ -535,14 +538,14 @@
         // PST 1298 with a final result of Dec 14 10:31:59 PST 1299.
         double ms = daysToMillis(Grego::fieldsToDay(gyear, UCAL_DECEMBER, 1));
 
-        umtx_lock(&astroLock);
+        umtx_lock(astroLock());
         if(gChineseCalendarAstro == NULL) {
             gChineseCalendarAstro = new CalendarAstronomer();
             ucln_i18n_registerCleanup(UCLN_I18N_CHINESE_CALENDAR, calendar_chinese_cleanup);
         }
         gChineseCalendarAstro->setTime(ms);
         UDate solarLong = gChineseCalendarAstro->getSunTime(CalendarAstronomer::WINTER_SOLSTICE(), TRUE);
-        umtx_unlock(&astroLock);
+        umtx_unlock(astroLock());
 
         // Winter solstice is 270 degrees solar longitude aka Dongzhi
         cacheValue = (int32_t)millisToDays(solarLong);
@@ -565,14 +568,14 @@
  */
 int32_t ChineseCalendar::newMoonNear(double days, UBool after) const {
     
-    umtx_lock(&astroLock);
+    umtx_lock(astroLock());
     if(gChineseCalendarAstro == NULL) {
         gChineseCalendarAstro = new CalendarAstronomer();
         ucln_i18n_registerCleanup(UCLN_I18N_CHINESE_CALENDAR, calendar_chinese_cleanup);
     }
     gChineseCalendarAstro->setTime(daysToMillis(days));
     UDate newMoon = gChineseCalendarAstro->getMoonTime(CalendarAstronomer::NEW_MOON(), after);
-    umtx_unlock(&astroLock);
+    umtx_unlock(astroLock());
     
     return (int32_t) millisToDays(newMoon);
 }
@@ -597,14 +600,14 @@
  */
 int32_t ChineseCalendar::majorSolarTerm(int32_t days) const {
     
-    umtx_lock(&astroLock);
+    umtx_lock(astroLock());
     if(gChineseCalendarAstro == NULL) {
         gChineseCalendarAstro = new CalendarAstronomer();
         ucln_i18n_registerCleanup(UCLN_I18N_CHINESE_CALENDAR, calendar_chinese_cleanup);
     }
     gChineseCalendarAstro->setTime(daysToMillis(days));
     UDate solarLongitude = gChineseCalendarAstro->getSunLongitude();
-    umtx_unlock(&astroLock);
+    umtx_unlock(astroLock());
 
     // Compute (floor(solarLongitude / (pi/6)) + 2) % 12
     int32_t term = ( ((int32_t)(6 * solarLongitude / CalendarAstronomer::PI)) + 2 ) % 12;
diff --git a/icu4c/source/i18n/dtfmtsym.cpp b/icu4c/source/i18n/dtfmtsym.cpp
index ae7d292..42cf5c5 100644
--- a/icu4c/source/i18n/dtfmtsym.cpp
+++ b/icu4c/source/i18n/dtfmtsym.cpp
@@ -235,8 +235,6 @@
 
 static const char gContextTransformsTag[]="contextTransforms";
 
-static UMutex LOCK = U_MUTEX_INITIALIZER;
-
 /**
  * Jitterbug 2974: MSVC has a bug whereby new X[0] behaves badly.
  * Work around this.
@@ -1248,6 +1246,7 @@
 DateFormatSymbols::getZoneStrings(int32_t& rowCount, int32_t& columnCount) const
 {
     const UnicodeString **result = NULL;
+    static UMutex LOCK = U_MUTEX_INITIALIZER;
 
     umtx_lock(&LOCK);
     if (fZoneStrings == NULL) {
diff --git a/icu4c/source/i18n/dtitvfmt.cpp b/icu4c/source/i18n/dtitvfmt.cpp
index 1de7652..93ceff3 100644
--- a/icu4c/source/i18n/dtitvfmt.cpp
+++ b/icu4c/source/i18n/dtitvfmt.cpp
@@ -82,7 +82,10 @@
 // Mutex, protects access to fDateFormat, fFromCalendar and fToCalendar.
 //        Needed because these data members are modified by const methods of DateIntervalFormat.
 
-static UMutex gFormatterMutex = U_MUTEX_INITIALIZER;
+static UMutex *gFormatterMutex() {
+    static UMutex m = U_MUTEX_INITIALIZER;
+    return &m;
+}
 
 DateIntervalFormat* U_EXPORT2
 DateIntervalFormat::createInstance(const UnicodeString& skeleton,
@@ -168,7 +171,7 @@
         delete fTimePattern;
         delete fDateTimeFormat;
         {
-            Mutex lock(&gFormatterMutex);
+            Mutex lock(gFormatterMutex());
             if ( itvfmt.fDateFormat ) {
                 fDateFormat = (SimpleDateFormat*)itvfmt.fDateFormat->clone();
             } else {
@@ -230,7 +233,7 @@
     if ((fInfo != fmt->fInfo) && (fInfo == NULL || fmt->fInfo == NULL)) {return FALSE;}
     if (fInfo && fmt->fInfo && (*fInfo != *fmt->fInfo )) {return FALSE;}
     {
-        Mutex lock(&gFormatterMutex);
+        Mutex lock(gFormatterMutex());
         if (fDateFormat != fmt->fDateFormat && (fDateFormat == NULL || fmt->fDateFormat == NULL)) {return FALSE;}
         if (fDateFormat && fmt->fDateFormat && (*fDateFormat != *fmt->fDateFormat)) {return FALSE;}
     }
@@ -292,7 +295,7 @@
     handler.setAcceptFirstOnly(TRUE);
     int8_t ignore;
 
-    Mutex lock(&gFormatterMutex);
+    Mutex lock(gFormatterMutex());
     return formatIntervalImpl(*dtInterval, appendTo, ignore, handler, status);
 }
 
@@ -309,7 +312,7 @@
     auto handler = result->getHandler(status);
     handler.setCategory(UFIELD_CATEGORY_DATE);
     {
-        Mutex lock(&gFormatterMutex);
+        Mutex lock(gFormatterMutex());
         formatIntervalImpl(dtInterval, string, firstIndex, handler, status);
     }
     handler.getError(status);
@@ -341,7 +344,7 @@
     handler.setAcceptFirstOnly(TRUE);
     int8_t ignore;
 
-    Mutex lock(&gFormatterMutex);
+    Mutex lock(gFormatterMutex());
     return formatImpl(fromCalendar, toCalendar, appendTo, ignore, handler, status);
 }
 
@@ -359,7 +362,7 @@
     auto handler = result->getHandler(status);
     handler.setCategory(UFIELD_CATEGORY_DATE);
     {
-        Mutex lock(&gFormatterMutex);
+        Mutex lock(gFormatterMutex());
         formatImpl(fromCalendar, toCalendar, string, firstIndex, handler, status);
     }
     handler.getError(status);
@@ -597,7 +600,7 @@
 DateIntervalFormat::getTimeZone() const
 {
     if (fDateFormat != NULL) {
-        Mutex lock(&gFormatterMutex);
+        Mutex lock(gFormatterMutex());
         return fDateFormat->getTimeZone();
     }
     // If fDateFormat is NULL (unexpected), create default timezone.
diff --git a/icu4c/source/i18n/gender.cpp b/icu4c/source/i18n/gender.cpp
index 1456d86..50161e1 100644
--- a/icu4c/source/i18n/gender.cpp
+++ b/icu4c/source/i18n/gender.cpp
@@ -32,7 +32,7 @@
 #include "uhash.h"
 
 static UHashtable* gGenderInfoCache = NULL;
-static icu::UMutex gGenderMetaLock = U_MUTEX_INITIALIZER;
+
 static const char* gNeutralStr = "neutral";
 static const char* gMailTaintsStr = "maleTaints";
 static const char* gMixedNeutralStr = "mixedNeutral";
@@ -98,6 +98,7 @@
     return NULL;
   }
 
+  static UMutex gGenderMetaLock = U_MUTEX_INITIALIZER;
   const GenderInfo* result = NULL;
   const char* key = locale.getName();
   {
diff --git a/icu4c/source/i18n/islamcal.cpp b/icu4c/source/i18n/islamcal.cpp
index a002262..a024f4c 100644
--- a/icu4c/source/i18n/islamcal.cpp
+++ b/icu4c/source/i18n/islamcal.cpp
@@ -54,7 +54,6 @@
 
 // --- The cache --
 // cache of months
-static icu::UMutex astroLock = U_MUTEX_INITIALIZER;  // pod bay door lock
 static icu::CalendarCache *gMonthCache = NULL;
 static icu::CalendarAstronomer *gIslamicCalendarAstro = NULL;
 
@@ -471,6 +470,7 @@
 {
     double age = 0;
 
+    static UMutex astroLock = U_MUTEX_INITIALIZER;      // pod bay door lock
     umtx_lock(&astroLock);
     if(gIslamicCalendarAstro == NULL) {
         gIslamicCalendarAstro = new CalendarAstronomer();
diff --git a/icu4c/source/i18n/listformatter.cpp b/icu4c/source/i18n/listformatter.cpp
index ab8ef14..802ab0e 100644
--- a/icu4c/source/i18n/listformatter.cpp
+++ b/icu4c/source/i18n/listformatter.cpp
@@ -80,7 +80,6 @@
 
 
 static Hashtable* listPatternHash = nullptr;
-static UMutex listFormatterMutex = U_MUTEX_INITIALIZER;
 static const char STANDARD_STYLE[] = "standard";
 
 U_CDECL_BEGIN
@@ -145,6 +144,7 @@
     keyBuffer.append(':', errorCode).append(style, errorCode);
     UnicodeString key(keyBuffer.data(), -1, US_INV);
     ListFormatInternal* result = nullptr;
+    static UMutex listFormatterMutex = U_MUTEX_INITIALIZER;
     {
         Mutex m(&listFormatterMutex);
         if (listPatternHash == nullptr) {
diff --git a/icu4c/source/i18n/numfmt.cpp b/icu4c/source/i18n/numfmt.cpp
index 4b2eaac..7adf902 100644
--- a/icu4c/source/i18n/numfmt.cpp
+++ b/icu4c/source/i18n/numfmt.cpp
@@ -156,7 +156,6 @@
 
 // Static hashtable cache of NumberingSystem objects used by NumberFormat
 static UHashtable * NumberingSystem_cache = NULL;
-static icu::UMutex nscacheMutex = U_MUTEX_INITIALIZER;
 static icu::UInitOnce gNSCacheInitOnce = U_INITONCE_INITIALIZER;
 
 #if !UCONFIG_NO_SERVICE
@@ -1363,6 +1362,7 @@
         // TODO: Bad hash key usage, see ticket #8504.
         int32_t hashKey = desiredLocale.hashCode();
 
+        static icu::UMutex nscacheMutex = U_MUTEX_INITIALIZER;
         Mutex lock(&nscacheMutex);
         ns = (NumberingSystem *)uhash_iget(NumberingSystem_cache, hashKey);
         if (ns == NULL) {
diff --git a/icu4c/source/i18n/rbt.cpp b/icu4c/source/i18n/rbt.cpp
index 9cb1b0e..b440793 100644
--- a/icu4c/source/i18n/rbt.cpp
+++ b/icu4c/source/i18n/rbt.cpp
@@ -27,7 +27,6 @@
 
 UOBJECT_DEFINE_RTTI_IMPLEMENTATION(RuleBasedTransliterator)
 
-static UMutex transliteratorDataMutex = U_MUTEX_INITIALIZER;
 static Replaceable *gLockedText = NULL;
 
 void RuleBasedTransliterator::_construct(const UnicodeString& rules,
@@ -253,6 +252,8 @@
     //  Shared RBT data protected by transliteratorDataMutex.
     //
     // TODO(andy): Need a better scheme for handling this.
+
+    static UMutex transliteratorDataMutex = U_MUTEX_INITIALIZER;
     UBool needToLock;
     {
         Mutex m;
diff --git a/icu4c/source/i18n/rbtz.cpp b/icu4c/source/i18n/rbtz.cpp
index d98613f..4aa143c 100644
--- a/icu4c/source/i18n/rbtz.cpp
+++ b/icu4c/source/i18n/rbtz.cpp
@@ -146,10 +146,10 @@
     fUpToDate = FALSE;
 }
 
-static UMutex gLock = U_MUTEX_INITIALIZER;
 
 void
 RuleBasedTimeZone::completeConst(UErrorCode& status) const {
+    static UMutex gLock = U_MUTEX_INITIALIZER;
     if (U_FAILURE(status)) {
         return;
     }
diff --git a/icu4c/source/i18n/reldatefmt.cpp b/icu4c/source/i18n/reldatefmt.cpp
index 4f6f723..2b58e47 100644
--- a/icu4c/source/i18n/reldatefmt.cpp
+++ b/icu4c/source/i18n/reldatefmt.cpp
@@ -51,8 +51,6 @@
 
 // Copied from uscript_props.cpp
 
-static icu::UMutex gBrkIterMutex = U_MUTEX_INITIALIZER;
-
 U_NAMESPACE_BEGIN
 
 // RelativeDateTimeFormatter specific data for a single locale
@@ -1186,6 +1184,7 @@
 
     // Must guarantee that one thread at a time accesses the shared break
     // iterator.
+    static icu::UMutex gBrkIterMutex = U_MUTEX_INITIALIZER;
     Mutex lock(&gBrkIterMutex);
     str.toTitle(
             fOptBreakIterator->get(),
diff --git a/icu4c/source/i18n/simpletz.cpp b/icu4c/source/i18n/simpletz.cpp
index 57a7ba8..cacfa18 100644
--- a/icu4c/source/i18n/simpletz.cpp
+++ b/icu4c/source/i18n/simpletz.cpp
@@ -1077,13 +1077,13 @@
  *         allocate it in the constructors. This would be a more intrusive change, but doable
  *         if performance turns out to be an issue.
  */
-static UMutex gLock = U_MUTEX_INITIALIZER;
 
 void
 SimpleTimeZone::checkTransitionRules(UErrorCode& status) const {
     if (U_FAILURE(status)) {
         return;
     }
+    static UMutex gLock = U_MUTEX_INITIALIZER;
     umtx_lock(&gLock);
     if (!transitionRulesInitialized) {
         SimpleTimeZone *ncThis = const_cast<SimpleTimeZone*>(this);
diff --git a/icu4c/source/i18n/smpdtfmt.cpp b/icu4c/source/i18n/smpdtfmt.cpp
index 9ab7657..be0ced5 100644
--- a/icu4c/source/i18n/smpdtfmt.cpp
+++ b/icu4c/source/i18n/smpdtfmt.cpp
@@ -230,7 +230,10 @@
 static const int32_t HEBREW_CAL_CUR_MILLENIUM_START_YEAR = 5000;
 static const int32_t HEBREW_CAL_CUR_MILLENIUM_END_YEAR = 6000;
 
-static UMutex LOCK = U_MUTEX_INITIALIZER;
+static UMutex *LOCK() {
+    static UMutex m = U_MUTEX_INITIALIZER;
+    return &m;
+}
 
 UOBJECT_DEFINE_RTTI_IMPLEMENTATION(SimpleDateFormat)
 
@@ -1263,14 +1266,14 @@
     if ( fDateOverride.isBogus() && fTimeOverride.isBogus() ) {
         return;
     }
-    umtx_lock(&LOCK);
+    umtx_lock(LOCK());
     if (fSharedNumberFormatters == NULL) {
         fSharedNumberFormatters = allocSharedNumberFormatters();
         if (fSharedNumberFormatters == NULL) {
             status = U_MEMORY_ALLOCATION_ERROR;
         }
     }
-    umtx_unlock(&LOCK);
+    umtx_unlock(LOCK());
 
     if (U_FAILURE(status)) {
         return;
@@ -4198,7 +4201,7 @@
 TimeZoneFormat *
 SimpleDateFormat::tzFormat(UErrorCode &status) const {
     if (fTimeZoneFormat == NULL) {
-        umtx_lock(&LOCK);
+        umtx_lock(LOCK());
         {
             if (fTimeZoneFormat == NULL) {
                 TimeZoneFormat *tzfmt = TimeZoneFormat::createInstance(fLocale, status);
@@ -4209,7 +4212,7 @@
                 const_cast<SimpleDateFormat *>(this)->fTimeZoneFormat = tzfmt;
             }
         }
-        umtx_unlock(&LOCK);
+        umtx_unlock(LOCK());
     }
     return fTimeZoneFormat;
 }
diff --git a/icu4c/source/i18n/translit.cpp b/icu4c/source/i18n/translit.cpp
index 59025be..7d9c719 100644
--- a/icu4c/source/i18n/translit.cpp
+++ b/icu4c/source/i18n/translit.cpp
@@ -91,7 +91,10 @@
 /**
  * The mutex controlling access to registry object.
  */
-static icu::UMutex registryMutex = U_MUTEX_INITIALIZER;
+static icu::UMutex *registryMutex() {
+    static icu::UMutex m = U_MUTEX_INITIALIZER;
+    return &m;
+}
 
 /**
  * System transliterator registry; non-null when initialized.
@@ -978,11 +981,11 @@
     TransliteratorAlias* alias = 0;
     Transliterator* t = 0;
 
-    umtx_lock(&registryMutex);
+    umtx_lock(registryMutex());
     if (HAVE_REGISTRY(ec)) {
         t = registry->get(id, alias, ec);
     }
-    umtx_unlock(&registryMutex);
+    umtx_unlock(registryMutex());
 
     if (U_FAILURE(ec)) {
         delete t;
@@ -1010,11 +1013,11 @@
             alias = 0;
 
             // Step 2. reget
-            umtx_lock(&registryMutex);
+            umtx_lock(registryMutex());
             if (HAVE_REGISTRY(ec)) {
                 t = registry->reget(id, parser, alias, ec);
             }
-            umtx_unlock(&registryMutex);
+            umtx_unlock(registryMutex());
 
             // Step 3. Loop back around!
         } else {
@@ -1212,7 +1215,7 @@
 void U_EXPORT2 Transliterator::registerFactory(const UnicodeString& id,
                                      Transliterator::Factory factory,
                                      Transliterator::Token context) {
-    Mutex lock(&registryMutex);
+    Mutex lock(registryMutex());
     UErrorCode ec = U_ZERO_ERROR;
     if (HAVE_REGISTRY(ec)) {
         _registerFactory(id, factory, context);
@@ -1251,7 +1254,7 @@
  * @see #unregister
  */
 void U_EXPORT2 Transliterator::registerInstance(Transliterator* adoptedPrototype) {
-    Mutex lock(&registryMutex);
+    Mutex lock(registryMutex());
     UErrorCode ec = U_ZERO_ERROR;
     if (HAVE_REGISTRY(ec)) {
         _registerInstance(adoptedPrototype);
@@ -1265,7 +1268,7 @@
 
 void U_EXPORT2 Transliterator::registerAlias(const UnicodeString& aliasID,
                                              const UnicodeString& realID) {
-    Mutex lock(&registryMutex);
+    Mutex lock(registryMutex());
     UErrorCode ec = U_ZERO_ERROR;
     if (HAVE_REGISTRY(ec)) {
         _registerAlias(aliasID, realID);
@@ -1287,7 +1290,7 @@
 
  */
 void U_EXPORT2 Transliterator::unregister(const UnicodeString& ID) {
-    Mutex lock(&registryMutex);
+    Mutex lock(registryMutex());
     UErrorCode ec = U_ZERO_ERROR;
     if (HAVE_REGISTRY(ec)) {
         registry->remove(ID);
@@ -1302,7 +1305,7 @@
  */
 int32_t U_EXPORT2 Transliterator::countAvailableIDs(void) {
     int32_t retVal = 0;
-    Mutex lock(&registryMutex);
+    Mutex lock(registryMutex());
     UErrorCode ec = U_ZERO_ERROR;
     if (HAVE_REGISTRY(ec)) {
         retVal = registry->countAvailableIDs();
@@ -1318,12 +1321,12 @@
  */
 const UnicodeString& U_EXPORT2 Transliterator::getAvailableID(int32_t index) {
     const UnicodeString* result = NULL;
-    umtx_lock(&registryMutex);
+    umtx_lock(registryMutex());
     UErrorCode ec = U_ZERO_ERROR;
     if (HAVE_REGISTRY(ec)) {
         result = &registry->getAvailableID(index);
     }
-    umtx_unlock(&registryMutex);
+    umtx_unlock(registryMutex());
     U_ASSERT(result != NULL); // fail if no registry
     return *result;
 }
@@ -1331,11 +1334,11 @@
 StringEnumeration* U_EXPORT2 Transliterator::getAvailableIDs(UErrorCode& ec) {
     if (U_FAILURE(ec)) return NULL;
     StringEnumeration* result = NULL;
-    umtx_lock(&registryMutex);
+    umtx_lock(registryMutex());
     if (HAVE_REGISTRY(ec)) {
         result = registry->getAvailableIDs();
     }
-    umtx_unlock(&registryMutex);
+    umtx_unlock(registryMutex());
     if (result == NULL) {
         ec = U_INTERNAL_TRANSLITERATOR_ERROR;
     }
@@ -1343,14 +1346,14 @@
 }
 
 int32_t U_EXPORT2 Transliterator::countAvailableSources(void) {
-    Mutex lock(&registryMutex);
+    Mutex lock(registryMutex());
     UErrorCode ec = U_ZERO_ERROR;
     return HAVE_REGISTRY(ec) ? _countAvailableSources() : 0;
 }
 
 UnicodeString& U_EXPORT2 Transliterator::getAvailableSource(int32_t index,
                                                   UnicodeString& result) {
-    Mutex lock(&registryMutex);
+    Mutex lock(registryMutex());
     UErrorCode ec = U_ZERO_ERROR;
     if (HAVE_REGISTRY(ec)) {
         _getAvailableSource(index, result);
@@ -1359,7 +1362,7 @@
 }
 
 int32_t U_EXPORT2 Transliterator::countAvailableTargets(const UnicodeString& source) {
-    Mutex lock(&registryMutex);
+    Mutex lock(registryMutex());
     UErrorCode ec = U_ZERO_ERROR;
     return HAVE_REGISTRY(ec) ? _countAvailableTargets(source) : 0;
 }
@@ -1367,7 +1370,7 @@
 UnicodeString& U_EXPORT2 Transliterator::getAvailableTarget(int32_t index,
                                                   const UnicodeString& source,
                                                   UnicodeString& result) {
-    Mutex lock(&registryMutex);
+    Mutex lock(registryMutex());
     UErrorCode ec = U_ZERO_ERROR;
     if (HAVE_REGISTRY(ec)) {
         _getAvailableTarget(index, source, result);
@@ -1377,7 +1380,7 @@
 
 int32_t U_EXPORT2 Transliterator::countAvailableVariants(const UnicodeString& source,
                                                const UnicodeString& target) {
-    Mutex lock(&registryMutex);
+    Mutex lock(registryMutex());
     UErrorCode ec = U_ZERO_ERROR;
     return HAVE_REGISTRY(ec) ? _countAvailableVariants(source, target) : 0;
 }
@@ -1386,7 +1389,7 @@
                                                    const UnicodeString& source,
                                                    const UnicodeString& target,
                                                    UnicodeString& result) {
-    Mutex lock(&registryMutex);
+    Mutex lock(registryMutex());
     UErrorCode ec = U_ZERO_ERROR;
     if (HAVE_REGISTRY(ec)) {
         _getAvailableVariant(index, source, target, result);
diff --git a/icu4c/source/i18n/tridpars.cpp b/icu4c/source/i18n/tridpars.cpp
index b276636..f54393b 100644
--- a/icu4c/source/i18n/tridpars.cpp
+++ b/icu4c/source/i18n/tridpars.cpp
@@ -50,7 +50,10 @@
 /**
  * The mutex controlling access to SPECIAL_INVERSES
  */
-static UMutex LOCK = U_MUTEX_INITIALIZER;
+static UMutex *LOCK() {
+    static UMutex m = U_MUTEX_INITIALIZER;
+    return &m;
+}
 
 TransliteratorIDParser::Specs::Specs(const UnicodeString& s, const UnicodeString& t,
                                      const UnicodeString& v, UBool sawS,
@@ -659,7 +662,7 @@
         bidirectional = FALSE;
     }
 
-    Mutex lock(&LOCK);
+    Mutex lock(LOCK());
 
     UnicodeString *tempus = new UnicodeString(inverseTarget);  // Used for null pointer check before usage.
     if (tempus == NULL) {
@@ -863,9 +866,9 @@
 
     UnicodeString* inverseTarget;
 
-    umtx_lock(&LOCK);
+    umtx_lock(LOCK());
     inverseTarget = (UnicodeString*) SPECIAL_INVERSES->get(specs.target);
-    umtx_unlock(&LOCK);
+    umtx_unlock(LOCK());
 
     if (inverseTarget != NULL) {
         // If the original ID contained "Any-" then make the
diff --git a/icu4c/source/i18n/tzfmt.cpp b/icu4c/source/i18n/tzfmt.cpp
index 4730455..5aa7af5 100644
--- a/icu4c/source/i18n/tzfmt.cpp
+++ b/icu4c/source/i18n/tzfmt.cpp
@@ -147,7 +147,10 @@
 static TextTrieMap *gShortZoneIdTrie = NULL;
 static icu::UInitOnce gShortZoneIdTrieInitOnce = U_INITONCE_INITIALIZER;
 
-static UMutex gLock = U_MUTEX_INITIALIZER;
+static UMutex *gLock() {
+    static UMutex m = U_MUTEX_INITIALIZER;
+    return &m;
+}
 
 U_CDECL_BEGIN
 /**
@@ -1382,12 +1385,12 @@
         return NULL;
     }
 
-    umtx_lock(&gLock);
+    umtx_lock(gLock());
     if (fTimeZoneGenericNames == NULL) {
         TimeZoneFormat *nonConstThis = const_cast<TimeZoneFormat *>(this);
         nonConstThis->fTimeZoneGenericNames = TimeZoneGenericNames::createInstance(fLocale, status);
     }
-    umtx_unlock(&gLock);
+    umtx_unlock(gLock());
 
     return fTimeZoneGenericNames;
 }
@@ -1398,7 +1401,7 @@
         return NULL;
     }
 
-    umtx_lock(&gLock);
+    umtx_lock(gLock());
     if (fTZDBTimeZoneNames == NULL) {
         TZDBTimeZoneNames *tzdbNames = new TZDBTimeZoneNames(fLocale);
         if (tzdbNames == NULL) {
@@ -1408,7 +1411,7 @@
             nonConstThis->fTZDBTimeZoneNames = tzdbNames;
         }
     }
-    umtx_unlock(&gLock);
+    umtx_unlock(gLock());
 
     return fTZDBTimeZoneNames;
 }
diff --git a/icu4c/source/i18n/tzgnames.cpp b/icu4c/source/i18n/tzgnames.cpp
index 5f5b7db..4e3ecb4 100644
--- a/icu4c/source/i18n/tzgnames.cpp
+++ b/icu4c/source/i18n/tzgnames.cpp
@@ -269,7 +269,10 @@
     return results;
 }
 
-static UMutex gLock = U_MUTEX_INITIALIZER;
+static UMutex *gLock() {
+    static UMutex m = U_MUTEX_INITIALIZER;
+    return &m;
+}
 
 class TZGNCore : public UMemory {
 public:
@@ -485,11 +488,11 @@
 
     const UChar *locname = NULL;
     TZGNCore *nonConstThis = const_cast<TZGNCore *>(this);
-    umtx_lock(&gLock);
+    umtx_lock(gLock());
     {
         locname = nonConstThis->getGenericLocationName(tzCanonicalID);
     }
-    umtx_unlock(&gLock);
+    umtx_unlock(gLock());
 
     if (locname == NULL) {
         name.setToBogus();
@@ -740,11 +743,11 @@
 
     const UChar *uplname = NULL;
     TZGNCore *nonConstThis = const_cast<TZGNCore *>(this);
-    umtx_lock(&gLock);
+    umtx_lock(gLock());
     {
         uplname = nonConstThis->getPartialLocationName(tzCanonicalID, mzID, isLong, mzDisplayName);
     }
-    umtx_unlock(&gLock);
+    umtx_unlock(gLock());
 
     if (uplname == NULL) {
         name.setToBogus();
@@ -1007,11 +1010,11 @@
 
     TZGNCore *nonConstThis = const_cast<TZGNCore *>(this);
 
-    umtx_lock(&gLock);
+    umtx_lock(gLock());
     {
         fGNamesTrie.search(text, start, (TextTrieMapSearchResultHandler *)&handler, status);
     }
-    umtx_unlock(&gLock);
+    umtx_unlock(gLock());
 
     if (U_FAILURE(status)) {
         return NULL;
@@ -1038,7 +1041,7 @@
 
     // All names are not yet loaded into the local trie.
     // Load all available names into the trie. This could be very heavy.
-    umtx_lock(&gLock);
+    umtx_lock(gLock());
     {
         if (!fGNamesTrieFullyLoaded) {
             StringEnumeration *tzIDs = TimeZone::createTimeZoneIDEnumeration(UCAL_ZONE_TYPE_CANONICAL, NULL, NULL, status);
@@ -1060,18 +1063,18 @@
             }
         }
     }
-    umtx_unlock(&gLock);
+    umtx_unlock(gLock());
 
     if (U_FAILURE(status)) {
         return NULL;
     }
 
-    umtx_lock(&gLock);
+    umtx_lock(gLock());
     {
         // now try it again
         fGNamesTrie.search(text, start, (TextTrieMapSearchResultHandler *)&handler, status);
     }
-    umtx_unlock(&gLock);
+    umtx_unlock(gLock());
 
     results = handler.getMatches(maxLen);
     if (results != NULL && maxLen > 0) {
@@ -1112,7 +1115,10 @@
 } TZGNCoreRef;
 
 // TZGNCore object cache handling
-static UMutex gTZGNLock = U_MUTEX_INITIALIZER;
+static UMutex *gTZGNLock() {
+    static UMutex m = U_MUTEX_INITIALIZER;
+    return &m;
+}
 static UHashtable *gTZGNCoreCache = NULL;
 static UBool gTZGNCoreCacheInitialized = FALSE;
 
@@ -1178,13 +1184,13 @@
 }
 
 TimeZoneGenericNames::~TimeZoneGenericNames() {
-    umtx_lock(&gTZGNLock);
+    umtx_lock(gTZGNLock());
     {
         U_ASSERT(fRef->refCount > 0);
         // Just decrement the reference count
         fRef->refCount--;
     }
-    umtx_unlock(&gTZGNLock);
+    umtx_unlock(gTZGNLock());
 }
 
 TimeZoneGenericNames*
@@ -1200,7 +1206,7 @@
 
     TZGNCoreRef *cacheEntry = NULL;
     {
-        Mutex lock(&gTZGNLock);
+        Mutex lock(gTZGNLock());
 
         if (!gTZGNCoreCacheInitialized) {
             // Create empty hashtable
@@ -1292,13 +1298,13 @@
 TimeZoneGenericNames::clone() const {
     TimeZoneGenericNames* other = new TimeZoneGenericNames();
     if (other) {
-        umtx_lock(&gTZGNLock);
+        umtx_lock(gTZGNLock());
         {
             // Just increments the reference count
             fRef->refCount++;
             other->fRef = fRef;
         }
-        umtx_unlock(&gTZGNLock);
+        umtx_unlock(gTZGNLock());
     }
     return other;
 }
diff --git a/icu4c/source/i18n/tznames.cpp b/icu4c/source/i18n/tznames.cpp
index 5a79c22..36d27ca 100644
--- a/icu4c/source/i18n/tznames.cpp
+++ b/icu4c/source/i18n/tznames.cpp
@@ -29,7 +29,10 @@
 U_NAMESPACE_BEGIN
 
 // TimeZoneNames object cache handling
-static UMutex gTimeZoneNamesLock = U_MUTEX_INITIALIZER;
+static UMutex *gTimeZoneNamesLock() {
+    static UMutex m = U_MUTEX_INITIALIZER;
+    return &m;
+}
 static UHashtable *gTimeZoneNamesCache = NULL;
 static UBool gTimeZoneNamesCacheInitialized = FALSE;
 
@@ -132,7 +135,7 @@
 }
 
 TimeZoneNamesDelegate::TimeZoneNamesDelegate(const Locale& locale, UErrorCode& status) {
-    Mutex lock(&gTimeZoneNamesLock);
+    Mutex lock(gTimeZoneNamesLock());
     if (!gTimeZoneNamesCacheInitialized) {
         // Create empty hashtable if it is not already initialized.
         gTimeZoneNamesCache = uhash_open(uhash_hashChars, uhash_compareChars, NULL, &status);
@@ -208,7 +211,7 @@
 }
 
 TimeZoneNamesDelegate::~TimeZoneNamesDelegate() {
-    umtx_lock(&gTimeZoneNamesLock);
+    umtx_lock(gTimeZoneNamesLock());
     {
         if (fTZnamesCacheEntry) {
             U_ASSERT(fTZnamesCacheEntry->refCount > 0);
@@ -216,7 +219,7 @@
             fTZnamesCacheEntry->refCount--;
         }
     }
-    umtx_unlock(&gTimeZoneNamesLock);
+    umtx_unlock(gTimeZoneNamesLock());
 }
 
 UBool
@@ -237,13 +240,13 @@
 TimeZoneNamesDelegate::clone() const {
     TimeZoneNamesDelegate* other = new TimeZoneNamesDelegate();
     if (other != NULL) {
-        umtx_lock(&gTimeZoneNamesLock);
+        umtx_lock(gTimeZoneNamesLock());
         {
             // Just increment the reference count
             fTZnamesCacheEntry->refCount++;
             other->fTZnamesCacheEntry = fTZnamesCacheEntry;
         }
-        umtx_unlock(&gTimeZoneNamesLock);
+        umtx_unlock(gTimeZoneNamesLock());
     }
     return other;
 }
diff --git a/icu4c/source/i18n/tznames_impl.cpp b/icu4c/source/i18n/tznames_impl.cpp
index 7bfbc04..5e3b478 100644
--- a/icu4c/source/i18n/tznames_impl.cpp
+++ b/icu4c/source/i18n/tznames_impl.cpp
@@ -49,8 +49,10 @@
 static const char* TZDBNAMES_KEYS[]               = {"ss", "sd"};
 static const int32_t TZDBNAMES_KEYS_SIZE = UPRV_LENGTHOF(TZDBNAMES_KEYS);
 
-static UMutex gTZDBNamesMapLock = U_MUTEX_INITIALIZER;
-static UMutex gDataMutex = U_MUTEX_INITIALIZER;
+static UMutex *gDataMutex() {
+    static UMutex m = U_MUTEX_INITIALIZER;
+    return &m;
+}
 
 static UHashtable* gTZDBNamesMap = NULL;
 static icu::UInitOnce gTZDBNamesMapInitOnce = U_INITONCE_INITIALIZER;
@@ -357,8 +359,6 @@
     return NULL;
 }
 
-// Mutex for protecting the lazy creation of the Trie node structure on the first call to search().
-static UMutex TextTrieMutex = U_MUTEX_INITIALIZER;
 
 // buildTrie() - The Trie node structure is needed.  Create it from the data that was
 //               saved at the time the ZoneStringFormatter was created.  The Trie is only
@@ -386,6 +386,10 @@
         //       the ICU atomic safe functions for assigning and testing.
         //       Don't test the pointer fLazyContents.
         //       Don't do unless it's really required.
+
+        // Mutex for protecting the lazy creation of the Trie node structure on the first call to search().
+        static UMutex TextTrieMutex = U_MUTEX_INITIALIZER;
+
         Mutex lock(&TextTrieMutex);
         if (fLazyContents != NULL) {
             TextTrieMap *nonConstThis = const_cast<TextTrieMap *>(this);
@@ -1210,7 +1214,7 @@
     TimeZoneNamesImpl *nonConstThis = const_cast<TimeZoneNamesImpl *>(this);
 
     {
-        Mutex lock(&gDataMutex);
+        Mutex lock(gDataMutex());
         UErrorCode status = U_ZERO_ERROR;
         znames = nonConstThis->loadMetaZoneNames(mzID, status);
         if (U_FAILURE(status)) { return name; }
@@ -1236,7 +1240,7 @@
     TimeZoneNamesImpl *nonConstThis = const_cast<TimeZoneNamesImpl *>(this);
 
     {
-        Mutex lock(&gDataMutex);
+        Mutex lock(gDataMutex());
         UErrorCode status = U_ZERO_ERROR;
         tznames = nonConstThis->loadTimeZoneNames(tzID, status);
         if (U_FAILURE(status)) { return name; }
@@ -1259,7 +1263,7 @@
     TimeZoneNamesImpl *nonConstThis = const_cast<TimeZoneNamesImpl *>(this);
 
     {
-        Mutex lock(&gDataMutex);
+        Mutex lock(gDataMutex());
         UErrorCode status = U_ZERO_ERROR;
         tznames = nonConstThis->loadTimeZoneNames(tzID, status);
         if (U_FAILURE(status)) { return name; }
@@ -1354,7 +1358,7 @@
     // Synchronize so that data is not loaded multiple times.
     // TODO: Consider more fine-grained synchronization.
     {
-        Mutex lock(&gDataMutex);
+        Mutex lock(gDataMutex());
 
         // First try of lookup.
         matches = doFind(handler, text, start, status);
@@ -1581,7 +1585,7 @@
     if (U_FAILURE(status)) return;
 
     {
-        Mutex lock(&gDataMutex);
+        Mutex lock(gDataMutex());
         internalLoadAllDisplayNames(status);
     }
 }
@@ -1598,7 +1602,7 @@
 
     // Load the time zone strings
     {
-        Mutex lock(&gDataMutex);
+        Mutex lock(gDataMutex());
         tznames = (void*) nonConstThis->loadTimeZoneNames(tzID, status);
         if (U_FAILURE(status)) { return; }
     }
@@ -1618,7 +1622,7 @@
                 } else {
                     // Load the meta zone strings
                     // Mutex is scoped to the "else" statement
-                    Mutex lock(&gDataMutex);
+                    Mutex lock(gDataMutex());
                     mznames = (void*) nonConstThis->loadMetaZoneNames(mzID, status);
                     if (U_FAILURE(status)) { return; }
                     // Note: when the metazone doesn't exist, in Java, loadMetaZoneNames returns
@@ -2243,6 +2247,7 @@
     U_ASSERT(status == U_ZERO_ERROR);   // already checked length above
     mzIDKey[mzID.length()] = 0;
 
+    static UMutex gTZDBNamesMapLock = U_MUTEX_INITIALIZER;
     umtx_lock(&gTZDBNamesMapLock);
     {
         void *cacheVal = uhash_get(gTZDBNamesMap, mzIDKey);
diff --git a/icu4c/source/i18n/zonemeta.cpp b/icu4c/source/i18n/zonemeta.cpp
index ddc8e29..0e3ee89 100644
--- a/icu4c/source/i18n/zonemeta.cpp
+++ b/icu4c/source/i18n/zonemeta.cpp
@@ -30,7 +30,10 @@
 #include "olsontz.h"
 #include "uinvchar.h"
 
-static icu::UMutex gZoneMetaLock = U_MUTEX_INITIALIZER;
+static icu::UMutex *gZoneMetaLock() {
+    static icu::UMutex m = U_MUTEX_INITIALIZER;
+    return &m;
+}
 
 // CLDR Canonical ID mapping table
 static UHashtable *gCanonicalIDCache = NULL;
@@ -263,11 +266,11 @@
     }
 
     // Check if it was already cached
-    umtx_lock(&gZoneMetaLock);
+    umtx_lock(gZoneMetaLock());
     {
         canonicalID = (const UChar *)uhash_get(gCanonicalIDCache, utzid);
     }
-    umtx_unlock(&gZoneMetaLock);
+    umtx_unlock(gZoneMetaLock());
 
     if (canonicalID != NULL) {
         return canonicalID;
@@ -348,7 +351,7 @@
         U_ASSERT(canonicalID != NULL);  // canocanilD must be non-NULL here
 
         // Put the resolved canonical ID to the cache
-        umtx_lock(&gZoneMetaLock);
+        umtx_lock(gZoneMetaLock());
         {
             const UChar* idInCache = (const UChar *)uhash_get(gCanonicalIDCache, utzid);
             if (idInCache == NULL) {
@@ -368,7 +371,7 @@
                 }
             }
         }
-        umtx_unlock(&gZoneMetaLock);
+        umtx_unlock(gZoneMetaLock());
     }
 
     return canonicalID;
@@ -446,14 +449,14 @@
         // Check if it was already cached
         UBool cached = FALSE;
         UBool singleZone = FALSE;
-        umtx_lock(&gZoneMetaLock);
+        umtx_lock(gZoneMetaLock());
         {
             singleZone = cached = gSingleZoneCountries->contains((void*)region);
             if (!cached) {
                 cached = gMultiZonesCountries->contains((void*)region);
             }
         }
-        umtx_unlock(&gZoneMetaLock);
+        umtx_unlock(gZoneMetaLock());
 
         if (!cached) {
             // We need to go through all zones associated with the region.
@@ -472,7 +475,7 @@
             delete ids;
 
             // Cache the result
-            umtx_lock(&gZoneMetaLock);
+            umtx_lock(gZoneMetaLock());
             {
                 UErrorCode ec = U_ZERO_ERROR;
                 if (singleZone) {
@@ -485,7 +488,7 @@
                     }
                 }
             }
-            umtx_unlock(&gZoneMetaLock);
+            umtx_unlock(gZoneMetaLock());
         }
 
         if (singleZone) {
@@ -572,11 +575,11 @@
     // get the mapping from cache
     const UVector *result = NULL;
 
-    umtx_lock(&gZoneMetaLock);
+    umtx_lock(gZoneMetaLock());
     {
         result = (UVector*) uhash_get(gOlsonToMeta, tzidUChars);
     }
-    umtx_unlock(&gZoneMetaLock);
+    umtx_unlock(gZoneMetaLock());
 
     if (result != NULL) {
         return result;
@@ -590,7 +593,7 @@
     }
 
     // put the new one into the cache
-    umtx_lock(&gZoneMetaLock);
+    umtx_lock(gZoneMetaLock());
     {
         // make sure it's already created
         result = (UVector*) uhash_get(gOlsonToMeta, tzidUChars);
@@ -618,7 +621,7 @@
             delete tmpResult;
         }
     }
-    umtx_unlock(&gZoneMetaLock);
+    umtx_unlock(gZoneMetaLock());
 
     return result;
 }
diff --git a/icu4c/source/io/locbund.cpp b/icu4c/source/io/locbund.cpp
index b239be6..c4ef195 100644
--- a/icu4c/source/io/locbund.cpp
+++ b/icu4c/source/io/locbund.cpp
@@ -45,9 +45,9 @@
 }
 U_CDECL_END
 
-static icu::UMutex gLock = U_MUTEX_INITIALIZER;
 static inline UNumberFormat * copyInvariantFormatter(ULocaleBundle *result, UNumberFormatStyle style) {
     U_NAMESPACE_USE
+    static UMutex gLock = U_MUTEX_INITIALIZER;
     Mutex lock(&gLock);
     if (result->fNumberFormat[style-1] == NULL) {
         if (gPosixNumberFormat[style-1] == NULL) {
diff --git a/icu4c/source/test/intltest/intltest.cpp b/icu4c/source/test/intltest/intltest.cpp
index 0cbf12e..201c546 100644
--- a/icu4c/source/test/intltest/intltest.cpp
+++ b/icu4c/source/test/intltest/intltest.cpp
@@ -1109,7 +1109,6 @@
   }
 }
 
-static UMutex messageMutex = U_MUTEX_INITIALIZER;
 
 void IntlTest::LL_message( UnicodeString message, UBool newline )
 {
@@ -1117,6 +1116,7 @@
     // All error messages generated by tests funnel through here.
     // Multithreaded tests can concurrently generate errors, requiring synchronization
     // to keep each message together.
+    static UMutex messageMutex = U_MUTEX_INITIALIZER;
     Mutex lock(&messageMutex);
 
     // string that starts with a LineFeed character and continues
diff --git a/icu4c/source/test/intltest/tsmthred.cpp b/icu4c/source/test/intltest/tsmthred.cpp
index 9126100..2c7528f 100644
--- a/icu4c/source/test/intltest/tsmthred.cpp
+++ b/icu4c/source/test/intltest/tsmthred.cpp
@@ -240,8 +240,14 @@
 //               platform's mutex support is at least superficially there.
 //
 //----------------------------------------------------------------------
-static UMutex         gTestMutexA          = U_MUTEX_INITIALIZER;
-static UConditionVar  gThreadsCountChanged = U_CONDITION_INITIALIZER;
+static UMutex *gTestMutexA() {
+    static UMutex m = U_MUTEX_INITIALIZER;
+    return &m;
+}
+static UConditionVar *gThreadsCountChanged() {
+    static UConditionVar cv = U_CONDITION_INITIALIZER;
+    return &cv;
+}
 
 static int     gThreadsStarted = 0;
 static int     gThreadsInMiddle = 0;
@@ -256,35 +262,35 @@
         // This is the code that each of the spawned threads runs.
         // All threads move together throught the started - middle - done sequence together,
         // waiting for all other threads to reach each point before advancing.
-        umtx_lock(&gTestMutexA);
+        umtx_lock(gTestMutexA());
         gThreadsStarted += 1;
-        umtx_condBroadcast(&gThreadsCountChanged);
+        umtx_condBroadcast(gThreadsCountChanged());
         while (gThreadsStarted < TESTMUTEX_THREAD_COUNT) {
             if (gThreadsInMiddle != 0) {
                 IntlTest::gTest->errln(
                     "%s:%d gThreadsInMiddle = %d. Expected 0.", __FILE__, __LINE__, gThreadsInMiddle);
                 return;
             }
-            umtx_condWait(&gThreadsCountChanged, &gTestMutexA);
+            umtx_condWait(gThreadsCountChanged(), gTestMutexA());
         }
 
         gThreadsInMiddle += 1;
-        umtx_condBroadcast(&gThreadsCountChanged);
+        umtx_condBroadcast(gThreadsCountChanged());
         while (gThreadsInMiddle < TESTMUTEX_THREAD_COUNT) {
             if (gThreadsDone != 0) {
                 IntlTest::gTest->errln(
                     "%s:%d gThreadsDone = %d. Expected 0.", __FILE__, __LINE__, gThreadsDone);
                 return;
             }
-            umtx_condWait(&gThreadsCountChanged, &gTestMutexA);
+            umtx_condWait(gThreadsCountChanged(), gTestMutexA());
         }
 
         gThreadsDone += 1;
-        umtx_condBroadcast(&gThreadsCountChanged);
+        umtx_condBroadcast(gThreadsCountChanged());
         while (gThreadsDone < TESTMUTEX_THREAD_COUNT) {
-            umtx_condWait(&gThreadsCountChanged, &gTestMutexA);
+            umtx_condWait(gThreadsCountChanged(), gTestMutexA());
         }
-        umtx_unlock(&gTestMutexA);
+        umtx_unlock(gTestMutexA());
     }
 };
 
@@ -295,7 +301,7 @@
     gThreadsDone = 0;
     int32_t i = 0;
     TestMutexThread  threads[TESTMUTEX_THREAD_COUNT];
-    umtx_lock(&gTestMutexA);
+    umtx_lock(gTestMutexA());
     for (i=0; i<TESTMUTEX_THREAD_COUNT; i++) {
         if (threads[i].start() != 0) {
             errln("%s:%d Error starting thread %d", __FILE__, __LINE__, i);
@@ -315,13 +321,13 @@
             errln("%s:%d gThreadsDone=%d. Expected 0.", __FILE__, __LINE__, gThreadsStarted);
             return;
         }
-        umtx_condWait(&gThreadsCountChanged, &gTestMutexA);
+        umtx_condWait(gThreadsCountChanged(), gTestMutexA());
     }
 
     while (gThreadsDone < TESTMUTEX_THREAD_COUNT) {
-        umtx_condWait(&gThreadsCountChanged, &gTestMutexA);
+        umtx_condWait(gThreadsCountChanged(), gTestMutexA());
     }
-    umtx_unlock(&gTestMutexA);
+    umtx_unlock(gTestMutexA());
 
     for (i=0; i<TESTMUTEX_THREAD_COUNT; i++) {
         threads[i].join();
@@ -1166,8 +1172,14 @@
     bool  fFinished;
 };
 
-static UMutex gCTMutex = U_MUTEX_INITIALIZER;
-static UConditionVar gCTConditionVar = U_CONDITION_INITIALIZER;
+static UMutex *gCTMutex() {
+    static UMutex m = U_MUTEX_INITIALIZER;
+    return &m;
+}
+static UConditionVar *gCTConditionVar() {
+    static UConditionVar cv = U_CONDITION_INITIALIZER;
+    return &cv;
+}
 int gConditionTestOne = 1;   // Value one. Non-const, extern linkage to inhibit
                              //   compiler assuming a known value.
 int gStartedThreads;
@@ -1177,26 +1189,26 @@
 
 // Worker thread function.
 void CondThread::run() {
-    umtx_lock(&gCTMutex);
+    umtx_lock(gCTMutex());
     gStartedThreads += gConditionTestOne;
-    umtx_condBroadcast(&gCTConditionVar);
+    umtx_condBroadcast(gCTConditionVar());
 
     while (gStartedThreads < NUMTHREADS) {
         if (gFinishedThreads != 0) {
             IntlTest::gTest->errln("File %s, Line %d: Error, gStartedThreads = %d, gFinishedThreads = %d",
                              __FILE__, __LINE__, gStartedThreads, gFinishedThreads);
         }
-        umtx_condWait(&gCTConditionVar, &gCTMutex);
+        umtx_condWait(gCTConditionVar(), gCTMutex());
     }
 
     gFinishedThreads += gConditionTestOne;
     fFinished = true;
-    umtx_condBroadcast(&gCTConditionVar);
+    umtx_condBroadcast(gCTConditionVar());
 
     while (gFinishedThreads < NUMTHREADS) {
-        umtx_condWait(&gCTConditionVar, &gCTMutex);
+        umtx_condWait(gCTConditionVar(), gCTMutex());
     }
-    umtx_unlock(&gCTMutex);
+    umtx_unlock(gCTMutex());
 }
 
 void MultithreadTest::TestConditionVariables() {
@@ -1204,7 +1216,7 @@
     gFinishedThreads = 0;
     int i;
 
-    umtx_lock(&gCTMutex);
+    umtx_lock(gCTMutex());
     CondThread *threads[NUMTHREADS];
     for (i=0; i<NUMTHREADS; ++i) {
         threads[i] = new CondThread;
@@ -1212,14 +1224,14 @@
     }
 
     while (gStartedThreads < NUMTHREADS) {
-        umtx_condWait(&gCTConditionVar, &gCTMutex);
+        umtx_condWait(gCTConditionVar(), gCTMutex());
     }
 
     while (gFinishedThreads < NUMTHREADS) {
-        umtx_condWait(&gCTConditionVar, &gCTMutex);
+        umtx_condWait(gCTConditionVar(), gCTMutex());
     }
 
-    umtx_unlock(&gCTMutex);
+    umtx_unlock(gCTMutex());
 
     for (i=0; i<NUMTHREADS; ++i) {
         assertTrue(WHERE, threads[i]->fFinished);
@@ -1280,7 +1292,7 @@
         return result;
     }
 
-    umtx_lock(&gCTMutex);
+    umtx_lock(gCTMutex());
     bool firstObject = (gObjectsCreated == 0);
     if (firstObject) {
         // Force the first object creation that comes through to wait
@@ -1291,10 +1303,10 @@
         // early, to keep subsequent threads from entering this path.
         gObjectsCreated = 1;
         while (gObjectsCreated < 3) {
-            umtx_condWait(&gCTConditionVar, &gCTMutex);
+            umtx_condWait(gCTConditionVar(), gCTMutex());
         }
     }
-    umtx_unlock(&gCTMutex);
+    umtx_unlock(gCTMutex());
 
     const UCTMultiThreadItem *result =
         new UCTMultiThreadItem(fLoc.getLanguage());
@@ -1306,12 +1318,12 @@
  
     // Log that we created an object. The first object was already counted,
     //    don't do it again.
-    umtx_lock(&gCTMutex);
+    umtx_lock(gCTMutex());
     if (!firstObject) {
         gObjectsCreated += 1;
     }
-    umtx_condBroadcast(&gCTConditionVar);
-    umtx_unlock(&gCTMutex);
+    umtx_condBroadcast(gCTConditionVar());
+    umtx_unlock(gCTMutex());
 
     return result;
 }