为什么部分HandlerThread的run()方法是同步的?

时间:2017-06-12 21:50:29

标签: java android multithreading synchronized android-handler

我通过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类的多个实例时,它会处理这种情况。

3 个答案:

答案 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; } 方法暂停的内部锁。