removeCallbacksAndMessages 是否序列化?
Does removeCallbacksAndMessages serialize?
举例来说,假设我有两个异步调用的方法,doDelayEventA 和 doEventB。为了简化事情,我们假设 doDelayEventA 将被调用一次,doEventB 将被调用一次。
doDelayEventA 启动一个计时器(实际上是一个处理程序),doEventB 将其杀死(如果它仍在等待中)。
private Handler mTimer;
public void doDelayEventA(){
mTimer = new Handler();
mTimer.postDelayed(new Runnable() {
public void run() {
Log.d(LOG_TAG, "Event A: We want this to happen FIRST or not at all");
}
}, 1000);
}
public void doEventB(){
if (mTimer != null) {
mTimer.removeCallbacksAndMessages(null);
}
Log.d(LOG_TAG, "Event B: If it happens, it should ALWAYS happen LAST");
}
问题:removeCallbacksAndMessages 是否强制序列化,也就是说,它是否会阻止执行,直到 runnable 被删除或执行?我想确保在调用这两种方法的情况下,EventA Log 语句将始终先于 EventB Log 语句执行或根本不执行。
Does the removeCallbacksAndMessages force a serialization, that is, does it block execution until the runnable has been removed or executed?
如果 doEventB()
在主应用程序线程上执行(或者,更准确地说,在与 Handler
绑定的同一线程上),您应该处于正常状态。 Handler
为此使用 MessageQueue
,并且 MessageQueue
确实同步删除消息,至少在 Android 7.1.
但是:
这不是记录在案的行为 AFAIK,因此存在一些风险 Android 的其他版本表现不同
如果您在不同的线程上调用 doEventB()
,虽然应该没有线程同步问题(例如,ConcurrentModificationException
),但您可能会遇到竞争条件:doEventB()
在一个线程上调用,Runnable
在另一个线程上开始执行,并且 doEventB()
日志消息发生在 Runnable
日志消息
之前
举例来说,假设我有两个异步调用的方法,doDelayEventA 和 doEventB。为了简化事情,我们假设 doDelayEventA 将被调用一次,doEventB 将被调用一次。
doDelayEventA 启动一个计时器(实际上是一个处理程序),doEventB 将其杀死(如果它仍在等待中)。
private Handler mTimer;
public void doDelayEventA(){
mTimer = new Handler();
mTimer.postDelayed(new Runnable() {
public void run() {
Log.d(LOG_TAG, "Event A: We want this to happen FIRST or not at all");
}
}, 1000);
}
public void doEventB(){
if (mTimer != null) {
mTimer.removeCallbacksAndMessages(null);
}
Log.d(LOG_TAG, "Event B: If it happens, it should ALWAYS happen LAST");
}
问题:removeCallbacksAndMessages 是否强制序列化,也就是说,它是否会阻止执行,直到 runnable 被删除或执行?我想确保在调用这两种方法的情况下,EventA Log 语句将始终先于 EventB Log 语句执行或根本不执行。
Does the removeCallbacksAndMessages force a serialization, that is, does it block execution until the runnable has been removed or executed?
如果 doEventB()
在主应用程序线程上执行(或者,更准确地说,在与 Handler
绑定的同一线程上),您应该处于正常状态。 Handler
为此使用 MessageQueue
,并且 MessageQueue
确实同步删除消息,至少在 Android 7.1.
但是:
这不是记录在案的行为 AFAIK,因此存在一些风险 Android 的其他版本表现不同
如果您在不同的线程上调用
doEventB()
,虽然应该没有线程同步问题(例如,ConcurrentModificationException
),但您可能会遇到竞争条件:doEventB()
在一个线程上调用,Runnable
在另一个线程上开始执行,并且doEventB()
日志消息发生在Runnable
日志消息 之前