从Android中的事件产生的顺序线程

时间:2014-11-21 19:31:09

标签: android multithreading

我有一个事件在服务中发现的runnable中触发。

主要的runnable由TimerTask启动。此主runnable中的事件应该依次生成worker threads

threads应该按照它们产生的顺序工作并完成。

在Android中执行此操作的最佳方式是什么?

我看过AsyncTasksExexcutorThreadPool等信息,但我不知道什么是最佳做法。

我只需要一些处理此问题的方法的简短示例。

服务类看起来像这样:

 public onCreate(){

    runnable = new Runnable() {
       public void run(){
      object.addListener(new Listener() {
            public void onEvent(Event event) {
             //  Put Code here to spawn sequential worker threads ...
            }
      }
   }
}

我在方法和成员方面添加了什么以及onEvent中的内容?谢谢!

1 个答案:

答案 0 :(得分:3)

由于您谈论服务,我假设您的任务不必直接与用户界面交互。您可以使用ThreadPoolExecutor,它实现Executor接口。此代码片段将创建一个只包含一个线程的线程池,这意味着所有Runnable实例将按顺序执行。由于这只会为您的任务创建一个Executor,因此该方法不会阻止执行任何其他任务。

Executor tpe = new ThreadPoolExecutor(1, 1, 1, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>());

tpe.execute(new Runnable() {
    @Override
    public void run() {
        // Do your runnable task
    }
});

Executor将是您服务的成员变量,执行部分应该在您的onEvent方法中。

但是,如果您需要与用户界面进行交互,那么您可以使用AsyncTask来解决使用UI线程同步调用的问题。 AsyncTask需要在UI线程上创建,因此在您的情况下,这只有在UI线程触发onEvent时才有效。另请注意,您的Runnables将在您的活动可能使用的任何其他AsyncTask之间执行。因此,如果您在服务中泛洪AsyncTask队列,那么您最终可能会遇到似乎没有运行的任务,因为它们可能在队列中很长时间。另请注意,在Android版本的历史记录中,执行AsyncTasks的方式已更改:

  

首次引入时,AsyncTasks在单个上串行执行   背景线程。从DONUT开始,这被改成了一个池   允许多个任务并行运行的线程。从...开始   HONEYCOMB,任务在单个线程上执行以避免常见   并行执行导致的应用程序错误。 Source

从API级别11开始,您还可以使用executeOnExecutor在我们创建的ThreadPoolExecutor上执行AsyncTask。

Executor tpe = new ThreadPoolExecutor(1, 1, 1, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>());
AsyncTask asyncTask = new AsyncTask() {
    @Override
    protected Object doInBackground(Object[] objects) {
        return null;
    }
};

asyncTask.executeOnExecutor(tpe, params);

这段代码演示了序列化的执行行为。创建一次ThreadPoolExecutor,然后for循环将向ThreadPoolExecutor队列添加5个任务。 Runnable无名类将在任务开始时向控制台输出一条消息,然后它将在它结束之前至少休眠两秒,并显示刚刚结束的消息。

import java.util.concurrent.Executor;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class Test {
    public static void main(String[] args) {

        // Our thread pool consists of 1 thread
        final Executor tpe = new ThreadPoolExecutor(1, 1, 1, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>());


        for (int i=0; i<5; i++) {
            final int index = i;
            tpe.execute(new Runnable() {
                @Override
                public void run() {
                    System.out.println("Running task: " + index);

                    try {
                        // Sleeping at least 2 seconds to pretend to be doing something CPU intensive
                        Thread.sleep(2000);
                    } catch (InterruptedException e) {
                        // lets ignore this for simplicity
                    }

                    System.out.println("Finished task: " + index);
                }
            });
        }
    }
}

结果输出为:

Running task: 0
Finished task: 0
Running task: 1
Finished task: 1
Running task: 2
Finished task: 2
Running task: 3
Finished task: 3
Running task: 4
Finished task: 4

如果我们为了演示目的,通过用这段代码替换tpe变量初始化,为ThreadPool添加了一个额外的Thread:

final Executor tpe = new ThreadPoolExecutor(2, 2, 1, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>());

然后输出将指示它同时运行多个任务。

Running task: 0
Running task: 1
Finished task: 1
Finished task: 0
Running task: 2
Running task: 3
Finished task: 2
Finished task: 3
Running task: 4
Finished task: 4