【问题标题】:Android ThreadPool and BlockingQueue problemsAndroid ThreadPool 和 BlockingQueue 问题
【发布时间】:2013-09-29 03:36:20
【问题描述】:

所以我创建了一个单例线程池:

线程池.java

package utils;

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

import android.annotation.SuppressLint;
import android.os.Handler;
import android.os.Message;
import android.util.Log;

public class TaskManager {

    // Sets the amount of time an idle thread will wait for a task before
// terminating
private static final int KEEP_ALIVE_TIME = 30;

// Sets the Time Unit to seconds
private static final TimeUnit KEEP_ALIVE_TIME_UNIT;

private static final int CORE_POOL_SIZE = 2;

private static final int MAXIMUM_POOL_SIZE = 2;

// A queue of Runnable for the image download pool
private final BlockingQueue<Runnable> mTaskQueue;

// A managed pool of background download threads
private final ThreadPoolExecutor mTaskThreadPool;

private static TaskManager sInstance = null;

private Handler mHandler;

// A static block that sets class fields

static {
    // The time unit for "keep alive" is in seconds
    KEEP_ALIVE_TIME_UNIT = TimeUnit.SECONDS;

    // Creates a single static instance of PhotoManager
    if (sInstance == null) {
        sInstance = new TaskManager();
        Log.d("init", "new TaskManager");
    }

}

public Handler getHandler() {
    return mHandler;
}

@SuppressLint("HandlerLeak")
private TaskManager() {
    mTaskQueue = new LinkedBlockingQueue<Runnable>();

    mTaskThreadPool = new ThreadPoolExecutor(CORE_POOL_SIZE,
            MAXIMUM_POOL_SIZE, KEEP_ALIVE_TIME, KEEP_ALIVE_TIME_UNIT,
            mTaskQueue);

    mHandler = new Handler() {
        public void handleMessage(Message m) {
            switch (m.what) {
            case 0:
                Log.d("start", (String) m.obj);
                break;
            case 1:
                Log.d("finish", (String) m.obj);
                break;
            }
        }
    };
}

public static TaskManager getInstance() {
    return sInstance;
}

public void addTask(Runnable task) {
    sInstance.mTaskQueue.offer(task);
    Log.d("size after add", Integer.toString(sInstance.mTaskQueue.size()));
}

public void startTask() {
    if (!sInstance.mTaskQueue.isEmpty()) {
        sInstance.mTaskThreadPool.execute(sInstance.mTaskQueue.poll());
        Log.d("size after start", Integer.toString(sInstance.mTaskQueue.size()));
    } else
        Log.d("queue empty", "yes");
        return;
}
}

在另一个班级我有一个按钮,

假设每次我点击那个按钮,它都会按顺序调用:

  • TaskManager.getinstance().addTask(task)
  • TaskManager.getinstance().startTask();

所以我点击了这个按钮一次,一切正常,

但如果我在所有任务完成后再次单击此按钮,

Log.d("queue empty", "yes"); 将被执行,

我的问题是,我真的不明白这个单例中的 BlockingQueue 会发生什么,谁能解释一下?谢谢你

【问题讨论】:

    标签: android threadpool


    【解决方案1】:

    我不知道具体在 Android 上的情况,但从 standard Java docs 看来,您似乎错误地使用了 BlockingQueueThreadPoolExecutor。您不应直接向BlockingQueue 添加任务。 ThreadPoolExecutor 类的类文档的“队列维护”部分和 getQueue() 方法的 the documentation 表明您不应与队列交互。

    相反,您应该使用ExecutorService 接口上的submit() 方法添加任务。这将使任务排队并在线程可用时立即开始执行。 Here 是一篇包含更多示例的文章。

    要修复,请删除addTask() 方法并将startTask() 修改为以下内容:

    public Future<Void> startTask(Runnable task) {
        return mTaskThreadPool.submit(task);
    }
    

    这也将允许您通过返回的 Future 取消任务。取消任务调用Future::cancel(true)

    【讨论】:

    • 太好了,感谢您的回答,但现在我有另一个问题,假设我想删除BlockingQueue 中的一个可运行文件,您知道怎么做吗?谢谢
    • 您是要删除特定任务还是仅删除队列中的一项任务?
    • ThreadExecutor 有一个 remove() 方法,它需要一个任务来删除。您必须将任务存储在其他地方,以便您可以将其传递给remove()。你想完成什么?
    • 所以我有几个按钮,它们会传递 Runnable 对象,然后如果我单击其中一个按钮两次,它将从 ThreadPool 中删除 Runnable 对象,这可能吗?
    • 我假设您正在尝试实现某种取消机制。它不会像调用 remove 那样简单。我猜如果任务已经开始,remove 不会取消。您可能必须在任务执行中实施检查以取消。
    【解决方案2】:

    显然在完成所有任务之后,

    ThreadPool 仍然处于活动状态,并且会立即获取所有给定的新任务,并添加到 TaskQueue,

    它会自动使队列为空,

    如果给定任务超过MAXIMUM_POOL_SIZE可用线程,它将再次开始排队任务......

    【讨论】:

      猜你喜欢
      • 2011-02-09
      • 2011-10-15
      • 2010-09-27
      • 1970-01-01
      • 1970-01-01
      • 2014-02-26
      • 2023-03-27
      • 1970-01-01
      • 2011-04-20
      相关资源
      最近更新 更多