Android 线程:在 "join" 启动之前是否需要等待线程启动?

Android Threads: is it necessary to wait for threads to start before "join"ing them?

我正在实施 Android "Service"。在其 "onCreate" 我想启动并等待另一个线程的完成。 ClientServiceLoop 是一个 Runnable,在 运行() 中有一个 while(true) 循环,具有简单的 return 条件。

@Override
public void onCreate() {
    super.onCreate();
    mClientServiceLoopThread = new Thread(mClientServiceLoop = new ClientServiceLoop(),
            "ClientServiceLoop");
    mClientServiceLoopThread.start();
    try {
        mClientServiceLoopThread.join();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}

我想知道的是,在我调用 start() 之后,是否保证新生成的线程已经调用了 Runnable 的 运行() 方法?我应该在调用 join() 之前等待线程启动吗?我无法找到有关确切保证这一点的文档。


对此进行测试,如果我不调用 start(),则立即加入 () returns。我想知道的是实际设置 isAlive() 的时间。我搜索了 Android sdk 但找不到设置 nativePeer 的位置。

--

    mClientServiceLoopThread = new Thread(mClientServiceLoop = new ClientServiceLoop(),
            "ClientServiceLoop");
    boolean b = mClientServiceLoopThread.isAlive(); // false
    try {
        mClientServiceLoopThread.join(); // internally just while(isAlive)...so returns immediately
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    mClientServiceLoopThread.start();//FIXME TESTING ONLY

-- Android 来源

/**
 * Blocks the current Thread (<code>Thread.currentThread()</code>) until
 * the receiver finishes its execution and dies.
 *
 * @throws InterruptedException if the current thread has been interrupted.
 *         The interrupted status of the current thread will be cleared before the exception is
 *         thrown.
 * @see Object#notifyAll
 * @see java.lang.ThreadDeath
 */
public final void join() throws InterruptedException {
    synchronized (lock) {
        while (isAlive()) {
            lock.wait();
        }
    }
}


/**
 * Returns <code>true</code> if the receiver has already been started and
 * still runs code (hasn't died yet). Returns <code>false</code> either if
 * the receiver hasn't been started yet or if it has already started and run
 * to completion and died.
 *
 * @return a <code>boolean</code> indicating the liveness of the Thread
 * @see Thread#start
 */
public final boolean isAlive() {
    return (nativePeer != 0);
}

nativePeer设置在哪里??

当主线程调用mClientServiceLoopThread.join()时;它将停止 运行 并等待 mClientServiceLoopThread 线程完成,因此您可以安全地调用开始然后加入。

从技术上讲,您可以在调用 start 之前调用 join

这里的问题是服务默认在应用程序的主线程(UI 线程)上执行代码。调用 join 将阻塞您的 UI 线程并使您的应用完全无响应。

不要这样做

启动线程后可以让onCreate()return正常,Service不会被销毁

好的,我确定地查到了这个。似乎 nativeCreate() 在调用 pthread_create 之前设置了 nativePeer。由于 pthread_create() 不保证线程在 returns 时启动,我不确定 Android 是否以相同的方式运行。好像他们已经处理了这件事。所以一旦 start() 被调用 join() 将保证等待。但是 join() 不会等待,除非 start() 被调用。

https://android.googlesource.com/platform/art/+/3c50a4b4ba6d7d9369ee9a0bd6d30bf4c9c79bb0/src/thread.cc

// Thread.start is synchronized, so we know that nativePeer is 0, and know that we're not racing to
// assign it.
env->SetIntField(java_peer, WellKnownClasses::java_lang_Thread_nativePeer,
               reinterpret_cast<jint>(child_thread));
...
int pthread_create_result = pthread_create(&new_pthread, &attr, Thread::CreateCallback, child_thread);