diff --git a/hbase-balancer/src/main/java/org/apache/hadoop/hbase/master/LoadBalancer.java b/hbase-balancer/src/main/java/org/apache/hadoop/hbase/master/LoadBalancer.java
index adead284943..055be811bcb 100644
--- a/hbase-balancer/src/main/java/org/apache/hadoop/hbase/master/LoadBalancer.java
+++ b/hbase-balancer/src/main/java/org/apache/hadoop/hbase/master/LoadBalancer.java
@@ -42,6 +42,23 @@ import org.apache.yetus.audience.InterfaceAudience;
* cluster.
*
* This class produces plans for the {@code AssignmentManager} to execute.
+ *
+ * About locking:
+ *
+ * - We will first call {@link #setClusterInfoProvider(ClusterInfoProvider)} and then
+ * {@link #initialize()} to initialize the balancer, and before calling {@link #initialize()}, we
+ * will never call any methods of this balancer. So these two methods do not need to be
+ * synchronized.
+ * - The {@link #balanceCluster(Map)} method will use the {@link ClusterMetrics} which is set by
+ * {@link #updateClusterMetrics(ClusterMetrics)}, and also lots of configurations, which could be
+ * changed by {@link #onConfigurationChange(Configuration)}, so the easier way is to make these
+ * three methods synchronized. And since there will be only one balancing thread, this will not
+ * impact performance too much.
+ * - The {@link #roundRobinAssignment(List, List)}, {@link #retainAssignment(Map, List)} and
+ * {@link #randomAssignment(RegionInfo, List)} could be called from multiple threads concurrently,
+ * so these three methods should not be synchronized, the implementation classes need to make sure
+ * that they are thread safe.
+ *
*/
@InterfaceAudience.Private
public interface LoadBalancer extends Stoppable, ConfigurationObserver {