在一个正在运行的线程Android中的wakelock

时间:2012-11-12 14:27:09

标签: android multithreading wakelock

我有这个简单的问题:

在一项服务中,我需要再运行2个以上的线程,我需要一个唤醒锁才能让它们被执行。我举个例子:

   wl.aquire();

    if (true) {
        mExecutorService.execute(thread1);
    }

    if (true) {
        mExecutorService.execute(thread2);
    }
   wl.release();

那么,在这种情况下,一旦2个线程开始或等待它们完成后唤醒锁定将被释放?

如果没有,我需要唤醒锁,以便在它们运行时保持正常运行,并且只有在最后一个线程完成时才释放它。我怎样才能做到这一点?我是否必须在线体的内部获得新的唤醒锁?

谢谢

3 个答案:

答案 0 :(得分:4)

根据Executor execute()文档:“在将来的某个时间执行给定的命令。该命令可以在新线程,池化线程或调用线程中执行,具体取决于执行者实施。“

所以这取决于你正在使用的具体执行程序。

我认为你应该使用submit()给执行官一份新工作。

如果您坚持使用Executor,则get()返回的Future上的submit()将会阻止,直到结果可用。

所以你可以打电话:

Future<Result> result_1 = mExecutorService.execute(Runnable1);
Future<Result> result_2 = mExecutorService.execute(Runnable2);

result_1.get();
result_2.get();

或者,您可以启动两个线程并等待它们完成:

Thread t1 = new Thread(Runnable1);
Thread t2 = new Thread(Runnable2);
t1.start();
t2.start();

t1.join();
t2.join();

希望这有帮助。

答案 1 :(得分:1)

假设您从AsyncTask或后台线程运行此代码。在调用[Thread.join()]

之前,您可以在所有线程上调用wl.release();

查看此link了解join()详细信息

EDIT1:在执行程序上,您还可以使用具有长等待值的awaitTermination()来等待它完成所有任务。以下代码来自官方java doc

void shutdownAndAwaitTermination(ExecutorService pool) {
   pool.shutdown(); // Disable new tasks from being submitted
   try {
     // Wait a while for existing tasks to terminate
     if (!pool.awaitTermination(60, TimeUnit.SECONDS)) {
       pool.shutdownNow(); // Cancel currently executing tasks
       // Wait a while for tasks to respond to being cancelled
       if (!pool.awaitTermination(60, TimeUnit.SECONDS))
           System.err.println("Pool did not terminate");
     }
   } catch (InterruptedException ie) {
     // (Re-)Cancel if current thread also interrupted
     pool.shutdownNow();
     // Preserve interrupt status
     Thread.currentThread().interrupt();
   }
 }

答案 2 :(得分:0)

请参阅http://developer.android.com/reference/android/os/PowerManager.WakeLock.html - 正确的方法是获取正在运行的两个线程中的唤醒锁。给出你的示例代码,你需要在thread1和thread2中有一个成员变量来存储wakelock,以及一些传递wakelock的方法,也许是这样的:

thread1.setWakelock(wl);
thread2.setWakelock(wl);

class Thread implements Runnable {
    PowerManager.Wakelock mWakelock;
    void setWakelock(PowerManager.Wakelock wl) {
        mWakelock = wl;
    }
}

然后在thread1和thread2中,你需要:

run() {
    mWakelock.acquire();
    ... your existing code here ...
    mWakelock.release();
}

请注意,这将起作用,因为默认情况下唤醒锁被引用计数;请参阅PowerManager.WakeLock.setReferenceCounted()。

等待线程完成使用thread.join()是错误的;它会阻止UI线程,你会得到一个ANR,就像你发现的那样。