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

标签 android multithreading service

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

有什么好的做法可以处理这个问题吗?现在我在服务中有一个哈希表,我在线程开始/结束时添加和删除一个标记。

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

最佳答案

您需要使用互斥锁来保护对 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

关于android - 所有线程完成后如何正确停止服务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12298026/

相关文章:

android - 默认选择为空的微调器

android - 将 Android SQLite 移植到 iOS

Python - 用户通过 CGI 输入。线程和读取文件

Angular 5 - 组件和服务之间的通信

c++ - 为什么我不能在 Windows Server 2008 中使用 system() 从服务启动批处理文件?

android - 开发软键盘 - 如何切换 View /服务?

android - Dagger 2 Presenter 注入(inject)返回空值

java - 如何在 roboguice 2.0 中注入(inject) LocationManager?

java - 定义线程安全类的两种方式的区别

c# - 获取错误 System.IO.IOException : 'The process cannot access the file'