diff --git a/mirai-core-api/src/commonMain/kotlin/event/EventChannel.kt b/mirai-core-api/src/commonMain/kotlin/event/EventChannel.kt
index 3ae779a7d..4d32e567a 100644
--- a/mirai-core-api/src/commonMain/kotlin/event/EventChannel.kt
+++ b/mirai-core-api/src/commonMain/kotlin/event/EventChannel.kt
@@ -17,6 +17,7 @@ package net.mamoe.mirai.event
 
 import kotlinx.coroutines.*
 import kotlinx.coroutines.channels.Channel
+import kotlinx.coroutines.sync.Mutex
 import net.mamoe.mirai.Bot
 import net.mamoe.mirai.event.Listener.ConcurrencyKind.CONCURRENT
 import net.mamoe.mirai.event.Listener.ConcurrencyKind.LOCKED
@@ -25,7 +26,6 @@ import net.mamoe.mirai.internal.event.GlobalEventListeners
 import net.mamoe.mirai.internal.event.Handler
 import net.mamoe.mirai.internal.event.ListenerRegistry
 import net.mamoe.mirai.internal.event.registerEventHandler
-import net.mamoe.mirai.utils.JavaFriendlyAPI
 import net.mamoe.mirai.utils.MiraiExperimentalApi
 import net.mamoe.mirai.utils.MiraiLogger
 import java.util.function.Consumer
@@ -52,12 +52,12 @@ import kotlin.reflect.KClass
  * - [EventChannel.subscribeOnce] 创建一个只监听单次的事件监听器.
  *
  * ### 获取事件通道
- * - [GlobalEventChannel]
- * - [Bot.eventChannel]
+ * - 全局事件通道: [GlobalEventChannel]
+ * - [BotEvent] 通道: [Bot.eventChannel]
  *
  * @see subscribe
  */
-public open class EventChannel<out BaseEvent : Event> @JvmOverloads constructor(
+public open class EventChannel<out BaseEvent : Event> @JvmOverloads internal constructor(
     public val baseEventClass: KClass<out BaseEvent>,
     /**
      * 此事件通道的默认 [CoroutineScope.coroutineContext]. 将会被添加给所有注册的事件监听器.
@@ -100,7 +100,7 @@ public open class EventChannel<out BaseEvent : Event> @JvmOverloads constructor(
      *
      * 若 [filter] 返回 `true`, 该事件将会被传给监听器. 否则将会被忽略, **监听器继续监听**.
      *
-     * ### 线性顺序
+     * ## 线性顺序
      * 多个 [filter] 的处理是线性且有顺序的. 若一个 [filter] 已经返回了 `false` (代表忽略这个事件), 则会立即忽略, 而不会传递给后续过滤器.
      *
      * 示例:
@@ -116,19 +116,19 @@ public open class EventChannel<out BaseEvent : Event> @JvmOverloads constructor(
      *     }
      * ```
      *
-     * ### 过滤器挂起
+     * ## 过滤器挂起
      * [filter] 允许挂起协程. **过滤器的挂起将被认为是事件监听器的挂起**.
      *
      * 过滤器挂起是否会影响事件处理,
      * 取决于 [subscribe] 时的 [Listener.ConcurrencyKind] 和 [Listener.EventPriority].
      *
-     * ### 过滤器异常处理
+     * ## 过滤器异常处理
      * 若 [filter] 抛出异常, 将被包装为 [ExceptionInEventChannelFilterException] 并重新抛出.
      *
      * @see filterIsInstance 过滤指定类型的事件
      */
     @JvmSynthetic
-    public fun filter(filter: suspend (event: @UnsafeVariance BaseEvent) -> Boolean): EventChannel<BaseEvent> {
+    public fun filter(filter: suspend (event: BaseEvent) -> Boolean): EventChannel<BaseEvent> {
         return object : EventChannel<BaseEvent>(baseEventClass, defaultCoroutineContext) {
             private inline val innerThis get() = this
 
@@ -253,15 +253,15 @@ public open class EventChannel<out BaseEvent : Event> @JvmOverloads constructor(
      * 每当 [事件广播][Event.broadcast] 时, [handler] 都会被执行.
      *
      *
-     * ### 创建监听
+     * ## 创建监听
      * 调用本函数:
      * ```
      * eventChannel.subscribe<E> { /* 会收到此通道中的所有是 E 的事件 */ }
      * ```
      *
-     * ### 生命周期
+     * ## 生命周期
      *
-     * #### 通过协程作用域管理监听器
+     * ### 通过协程作用域管理监听器
      * 本函数将会创建一个 [Job], 成为 [parentJob] 中的子任务. 可创建一个 [CoroutineScope] 来管理所有的监听器:
      * ```
      * val scope = CoroutineScope(SupervisorJob())
@@ -274,34 +274,40 @@ public open class EventChannel<out BaseEvent : Event> @JvmOverloads constructor(
      * scope.cancel() // 停止了协程作用域, 也就取消了两个监听器
      * ```
      *
-     * **注意**, 这个函数返回 [Listener], 它是一个 [CompletableJob]. 它会成为 [CoroutineScope] 的一个 [子任务][Job]
-     * ```
-     * runBlocking { // this: CoroutineScope
-     *   eventChannel.subscribe<Event> { /* 一些处理 */ } // 返回 Listener, 即 CompletableJob
-     * }
-     * // runBlocking 不会完结, 直到监听时创建的 `Listener` 被停止.
-     * // 它可能通过 Listener.cancel() 停止, 也可能自行返回 ListeningStatus.Stopped 停止.
-     * ```
+     * 这个函数返回 [Listener], 它是一个 [CompletableJob]. 它会成为 [parentJob] 或 [parentScope] 的一个 [子任务][Job]
      *
-     * #### 在监听器内部停止后续监听
-     * 当 [handler] 返回 [ListeningStatus.STOPPED] 时停止监听.
-     * 或 [Listener.complete] 后结束.
+     * ### 停止监听
+     * 如果 [handler] 返回 [ListeningStatus.STOPPED] 监听器将被停止.
      *
-     * ### 子类监听
-     * 监听父类事件, 也会同时监听其子类. 因此监听 [Event] 即可监听此通道中所有类型的事件.
+     * 也可以通过 [subscribe] 返回值 [Listener] 的 [Listener.complete]
      *
-     * ### 异常处理
+     * ## 监听器调度
+     * 监听器会被创建一个协程任务, 语义上在 [parentScope] 下运行.
+     * 通过 Kotlin [默认协程调度器][Dispatchers.Default] 在固定的全局共享线程池里执行, 除非有 [coroutineContext] 指定.
+     *
+     * 默认在 [handler] 中不能处理阻塞任务. 阻塞任务将会阻塞一个 Kotlin 全局协程调度线程并可能导致严重问题.
+     * 请通过 `withContext(Dispatchers.IO) { }` 等方法执行阻塞工作.
+     *
+     * ## 异常处理
      * - 当参数 [handler] 处理抛出异常时, 将会按如下顺序寻找 [CoroutineExceptionHandler] 处理异常:
      *   1. 参数 [coroutineContext]
      *   2. [EventChannel.defaultCoroutineContext]
      *   3. [Event.broadcast] 调用者的 [coroutineContext]
      *   4. 若事件为 [BotEvent], 则从 [BotEvent.bot] 获取到 [Bot], 进而在 [Bot.coroutineContext] 中寻找
      *   5. 若以上四个步骤均无法获取 [CoroutineExceptionHandler], 则使用 [MiraiLogger.Companion] 通过日志记录. 但这种情况理论上不应发生.
-     * - 事件处理时抛出异常不会停止监听器.
-     * - 建议在事件处理中 (即 [handler] 里) 处理异常,
-     *   或在参数 [coroutineContext] 中添加 [CoroutineExceptionHandler].
      *
      *
+     * 事件处理时抛出异常不会停止监听器.
+     *
+     * 建议在事件处理中 (即 [handler] 里) 处理异常,
+     * 或在参数 [coroutineContext] 中添加 [CoroutineExceptionHandler], 或通过 [EventChannel.exceptionHandler].
+     *
+     * ## 并发安全性
+     * 基于 [concurrency] 参数, 事件监听器可以被允许并行执行.
+     *
+     * - 若 [concurrency] 为 [Listener.ConcurrencyKind.CONCURRENT], [handler] 可能被并行调用, 需要保证并发安全.
+     * - 若 [concurrency] 为 [Listener.ConcurrencyKind.LOCKED], [handler] 会被 [Mutex] 限制.
+     *
      * @param coroutineContext 在 [defaultCoroutineContext] 的基础上, 给事件监听协程的额外的 [CoroutineContext].
      * @param concurrency 并发类型. 查看 [Listener.ConcurrencyKind]
      * @param priority  监听优先级,优先级越高越先执行
@@ -321,9 +327,6 @@ public open class EventChannel<out BaseEvent : Event> @JvmOverloads constructor(
      * @see subscribeOnce   只监听一次
      *
      * @see subscribeMessages       监听消息 DSL
-     * @see subscribeGroupMessages  监听群消息 DSL
-     * @see subscribeFriendMessages 监听好友消息 DSL
-     * @see subscribeTempMessages   监听临时会话消息 DSL
      */
     @JvmSynthetic
     public inline fun <reified E : Event> subscribe(
@@ -334,7 +337,7 @@ public open class EventChannel<out BaseEvent : Event> @JvmOverloads constructor(
     ): Listener<E> = subscribe(E::class, coroutineContext, concurrency, priority, handler)
 
     /**
-     * 与 [subscribe] 的区别是接受 [eventClass] 参数, 而不使用 `reified` 泛型
+     * 与 [subscribe] 的区别是接受 [eventClass] 参数, 而不使用 `reified` 泛型. 通常推荐使用具体化类型参数.
      *
      * @return 监听器实例. 此监听器已经注册到指定事件上, 在事件广播时将会调用 [handler]
      * @see subscribe
@@ -457,7 +460,6 @@ public open class EventChannel<out BaseEvent : Event> @JvmOverloads constructor(
      * @see subscribe
      * @see subscribeAlways
      */
-    @JavaFriendlyAPI
     @JvmOverloads
     @LowPriorityInOverloadResolution
     public fun <E : Event> subscribeAlways(
@@ -488,7 +490,6 @@ public open class EventChannel<out BaseEvent : Event> @JvmOverloads constructor(
      *
      * @see subscribe
      */
-    @JavaFriendlyAPI
     @JvmOverloads
     @LowPriorityInOverloadResolution
     public fun <E : Event> subscribe(
@@ -517,7 +518,6 @@ public open class EventChannel<out BaseEvent : Event> @JvmOverloads constructor(
      * @see subscribe
      * @see subscribeOnce
      */
-    @JavaFriendlyAPI
     @JvmOverloads
     @LowPriorityInOverloadResolution
     public fun <E : Event> subscribeOnce(
diff --git a/mirai-core-api/src/commonMain/kotlin/event/subscribeMessages.kt b/mirai-core-api/src/commonMain/kotlin/event/subscribeMessages.kt
index 02d41eccf..9ff7e9954 100644
--- a/mirai-core-api/src/commonMain/kotlin/event/subscribeMessages.kt
+++ b/mirai-core-api/src/commonMain/kotlin/event/subscribeMessages.kt
@@ -66,6 +66,12 @@ public typealias MessageEventSubscribersBuilder = MessageSubscribersBuilder<Mess
  *
  * @see EventChannel.subscribe 事件监听基础
  * @see EventChannel 事件通道
+ *
+ * @see subscribeFriendMessages
+ * @see subscribeGroupMessages
+ * @see subscribeTempMessages
+ * @see subscribeOtherClientMessages
+ * @see subscribeStrangerMessages
  */
 public fun <R> EventChannel<*>.subscribeMessages(
     coroutineContext: CoroutineContext = EmptyCoroutineContext,