所有线程完成后如何正确停止服务

时间:2012-09-06 10:28:26

标签: android multithreading service

我有一个服务,每次调用onStartCommand时都会触发一个新的网络线程。 当最后一个线程完成时,我必须停止服务。

有没有好的做法来处理这个问题?现在我在服务中有一个HashTable,我在线程开始/结束时添加和删除一个令牌。

每次线程完成时,都会从hashTable中删除令牌,如果哈希表为空,则我停止服务。这有效,但我知道它不是100%安全,因为旧线程可以在新线程将其标记插入哈希表之前检查哈希表的大小,因此,当实际有新线程启动时停止服务

1 个答案:

答案 0 :(得分:1)

你需要互斥来保护对hashTable的访问,如下所示: (假设pthreads和c ++,你必须相应地改变它,但我认为你明白了)

int getHashTableSize()
{
    pthread_mutex_lock(&yourMutex);
    int size = yourHashTable.size();
    pthread_mutex_unlock(&yourMutex);

    return size;
}

void addThread(TokenType &token)
{
    pthread_mutex_lock(&yourMutex);
    yourHashTable.addToken(token);
    pthread_mutex_unlock(&yourMutex);
}

void removeThread(TokenType &token)
{
    pthread_mutex_lock(&yourMutex);
    yourHashTable.removeToken(token);
    // check if yourHashTable is empty here, and stop service accordingly
    pthread_mutex_unlock(&yourMutex);
}

onStartCommand()
{
    pthread_mutex_lock(&yourMutex);
    // Logic for wake lock, thread creation, and adding to the hash table here
    // possibly need to consider recursive mutex locking
    pthread_mutex_unlock(&yourMutex);
}

当然,您必须相应地更改类型,并将这些方法添加到相应的类中。

另一种常见做法是通过调用join来等待线程完成,如下所示。当然,这仅在线程数为“静态”时才有用。如果你有一个应用程序,其中线程创建是动态的,那么第二种方法可能没那么有用。

for(int i = 0; i < numThreads; i++)
{
    // threadIds is a vector
    pthread_join(threadIds[i], NULL);
}
// At this point, all of your threads are complete