2017-06-12 80 views
0

我要通过HandlerThread源代码,我不明白为什么HandlerThread的run()方法的一部分是同步的?为什么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

也许其他线程锁定在'Thread'实例? (这通常是一个坏主意) – SLaks

+0

这可能是因为在该类的其他部分有“//如果线程已启动,请等到活套已创建 synchronized(this){”。 –

+0

这只是一个猜测(我不知道android),但它看起来像其他线程可能会调用'handlerThread.wait();'等待'mLooper'的值改变。 –

回答

0

它同步的原因是它需要为了调用notifyAll

JavaDoc

此方法应该仅由一个线程是 这个对象监视器的所有者被调用。甲线程成为对象的 监视器中的三种方式之一的所有者:

  • 通过执行对象的同步实例方法。

  • 通过执行同步对象的同步语句的主体。

  • 对于Class类型的对象,通过执行该类的同步静态方法。

一次只能有一个线程拥有对象的监视器。

0

notifyAll()的调用者必须在对象上持有锁,所以这就是为什么该语句在​​块中的原因。的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) { 
      } 
     } 
    } 
0

getLooper()方法应该返回的Looper实例连接到HandlerThread。此外,这个getter应该是线程安全的,原因很明显。所以实现无限期地等待,而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; 
} 

synchronized块是代码的最小部分,需要wait()方法挂起的内部锁。

相关问题