/* * Copyright (c) Facebook, Inc. and its affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ import android.support.annotation.UiThread; import android.support.annotation.WorkerThread; class ThreadDeadlock { Object lockA; // methods cannot run in parallel because both are on UI thread, thus no deadlock @UiThread public synchronized void noParallelismAOk() { synchronized (lockA) { } } @UiThread public void noParallelismBOk() { synchronized (lockA) { synchronized (this) { } } } Object lockB; // deadlock, one method on UI thread, one on Worker thread @UiThread public synchronized void annotatedUiThreadBad() { synchronized (lockB) { } } @WorkerThread public void annotatedWorkerThreadBad() { synchronized (lockB) { synchronized (this) { } } } Object lockC; // deadlock as above, but here assertions are used to determine thread status public synchronized void assertOnUIThreadBad() { OurThreadUtils.assertOnUiThread(); synchronized (lockC) { } } public void assertOnBackgroundThreadBad() { OurThreadUtils.assertOnBackgroundThread(); synchronized (lockC) { synchronized (this) { } } } Object lockD; // deadlock as above, though less certain because the only hint of concurrency is that // methods take locks public synchronized void notAnnotatedBadA() { synchronized (lockD) { } } public void notAnnotatedBBad() { synchronized (lockD) { synchronized (this) { } } } Object lockE, lockF, lockG; public void FP_sequentialEandGOk() { synchronized (lockE) { synchronized (lockF) { } } // at this point we still believe lockE is held synchronized (lockG) { } } public void FP_nestedGthenEOk() { synchronized (lockG) { synchronized (lockE) { } } } }