diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/animated/NativeAnimatedModule.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/animated/NativeAnimatedModule.java index 8a719ca35af1cc..d077d74ce4ec4c 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/animated/NativeAnimatedModule.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/animated/NativeAnimatedModule.java @@ -38,6 +38,7 @@ import java.util.List; import java.util.Queue; import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.atomic.AtomicReference; /** @@ -149,9 +150,18 @@ public long getBatchNumber() { } private class ConcurrentOperationQueue { - private final Queue mQueue = new ConcurrentLinkedQueue<>(); + private final Queue mQueue; @Nullable private UIThreadOperation mPeekedOperation = null; + ConcurrentOperationQueue() { + if (Build.VERSION.SDK_INT == Build.VERSION_CODES.S || Build.VERSION.SDK_INT == Build.VERSION_CODES.S_V2) { + // Android 12's ConcurrentLinkedQueue is flaky, use LinkedBlockingQueue instead. + mQueue = new LinkedBlockingQueue<>(); + } else { + mQueue = new ConcurrentLinkedQueue<>(); + } + } + @AnyThread boolean isEmpty() { return mQueue.isEmpty() && mPeekedOperation == null;