我通过HandlerThread源代码,我无法理解为什么HandlerThread的run()方法的一部分是同步的?
@Override
public void run() {
mTid = Process.myTid();
Looper.prepare();
synchronized (this) {
mLooper = Looper.myLooper();
notifyAll();
}
Process.setThreadPriority(mPriority);
onLooperPrepared();
Looper.loop();
mTid = -1;
}
我认为run()
方法是在它所属的线程上调用的,那么如何从多个线程到达它?
我希望当有人创建和启动同一个HandlerThread类的多个实例时,它会处理这种情况。
答案 0 :(得分:0)
同步的原因是,为了呼叫notifyAll
,需要它。
请参阅JavaDoc:
此方法只应由作为其所有者的线程调用 这个对象的监视器。线程成为对象的所有者 以三种方式之一监控:
执行该对象的同步实例方法。
通过执行在对象上同步的同步语句的主体。
对于Class类型的对象,通过执行该类的同步静态方法。
一次只能有一个线程拥有对象的监视器。
答案 1 :(得分:0)
notifyAll()
的调用者必须对该对象保持锁定,这就是该语句在synchronized
块中的原因。 mLooper
的赋值是同步的,以确保写入对其他线程可见,特别是HandlerThread#getLooper()
的调用者,其中包含以下代码:
// If the thread has been started, wait until the looper has been created.
synchronized (this) {
while (isAlive() && mLooper == null) {
try {
wait();
} catch (InterruptedException e) {
}
}
}
答案 2 :(得分:0)
getLooper()
方法应该返回连接到Looper
的{{1}}实例。此外,这个getter应该是线程安全的,原因很明显。因此,实现无限期地等待,而HandlerThread
方法在设置run()
后通知所有等待的线程。
mLooper
同步块是代码的最小部分,需要public void run() {
...
synchronized (this) {
mLooper = Looper.myLooper();
notifyAll();
}
...
}
public Looper getLooper() {
...
synchronized (this) {
while (isAlive() && mLooper == null) {
try {
wait();
} catch (InterruptedException e) {
}
}
}
return mLooper;
}
方法暂停的内部锁。