mirror of
https://github.com/vitorpamplona/amethyst.git
synced 2026-08-10 16:33:27 +00:00
The module-level mutable SimpleDateFormat formatters in these files were read concurrently — UI composition on the main thread, and LocalCache.justVerify calling dateFormatter() from background event- verification coroutines for failed-signature log lines. SimpleDateFormat is not thread-safe (mutable internal Calendar), and updateFormattersIfNeeded reassigned the field mid-format. Race produced corrupted timestamp strings and occasionally NumberFormatException inside format(). Replace the shared-var pattern with a small LocaleAwareFormatter that wraps a ThreadLocal<Pair<Locale, SimpleDateFormat>>. Each thread caches its own instance and rebuilds lazily when Locale.getDefault() changes — no locks, no contention, same allocation profile after warm-up. Apply the same pattern to CalendarTimeFormat for consistency; today its callers are all main-thread but the structure was identical.